在 Clojure/Compojure 中转义/清理用户输入

发布于 2024-09-02 22:15:44 字数 181 浏览 8 评论 0原文

我正在使用 Clojure/Ring/Compojure-0.4/Enlive 堆栈来构建 Web 应用程序。

此堆栈中是否有函数可以剥离 HTML 或 HTML 编码(即 <a>)用户提供的字符串为了防止XSS攻击?

I am using Clojure/Ring/Compojure-0.4/Enlive stack to build a web application.

Are there functions in this stack that would either strip HTML or HTML-encode (i.e. <a> to <a>) user-supplied strings in order to prevent XSS attacks?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-09-09 22:15:44

hiccup 中的 hiccup.util/escape-html 可以做到这一点。该函数曾经位于 Compojure 本身中(因为 hiccup 中的所有功能都曾经是 Compojure 的一部分)。这是一个足够简单的函数,您可以轻松地自己编写。

(defn escape-html
  "Change special characters into HTML character entities."
  [text]
  (.. #^String (as-str text)
    (replace "&" "&")
    (replace "<" "<")
    (replace ">" ">")
    (replace "\"" """)))

还有 clojure.contrib.string/escape,它采用 char -> 的映射。字符串转义序列和字符串并为您转义它。

user> (clojure.contrib.string/escape {\< "<" \> ">"} "<div>foo</div>")
"<div>foo</div>"

这让我觉得没有那么有用,因为你可能想转义多字符序列,而这不会让你这么做。但它可能适合您的 HTML 转义需求。

当然,还有许多用于此目的的 Java 库。您可以使用 Apache Commons 中的 StringEscapeUtils

(org.apache.commons.lang.StringEscapeUtils/escapeHtml4 some-string)

:不过,我觉得这个目的有点重量级。

hiccup.util/escape-html in hiccup does it. That function used to be in Compojure itself (since all of the functionality in hiccup used to be part of Compojure). It's a simple enough function that you could easily write it yourself though.

(defn escape-html
  "Change special characters into HTML character entities."
  [text]
  (.. #^String (as-str text)
    (replace "&" "&")
    (replace "<" "<")
    (replace ">" ">")
    (replace "\"" """)))

There's also clojure.contrib.string/escape, which takes a map of char -> string escape sequences and a string and escapes it for you.

user> (clojure.contrib.string/escape {\< "<" \> ">"} "<div>foo</div>")
"<div>foo</div>"

This strikes me as not as useful as it could be, because you might want to escape multi-character sequences and this won't let you. But it might work for your HTML-escaping needs.

And then there are many Java libraries for this, of course. You could use StringEscapeUtils from Apache Commons:

(org.apache.commons.lang.StringEscapeUtils/escapeHtml4 some-string)

This strikes me as a bit heavyweight for this purpose though.

洒一地阳光 2024-09-09 22:15:44

更新:我知道一定不止这些...

来自 ring-corering.util.codec 有一个名为 which work 的函数像这样:

user> (require '[ring.util.codec :as c])
nil
user> (c/url-encode "<a>")
"%3Ca%3E"
user> (c/url-decode "<a>")
"<a>"

这些是 java.net.URLEncoder 和 java.net.URLDecoder 的包装器。相同的命名空间提供了基于 Apache Commons 中的类来处理 Base64 编码的函数。


原始答案如下。

我不确定是否有公共函数可以执行此操作,但 Enlive 有两个名为 xml-str 的私有函数和 attr-str 执行此操作:(

(defn- xml-str
 "Like clojure.core/str but escapes < > and &."
 [x]
  (-> x str (.replace "&" "&") (.replace "<" "<") (.replace ">" ">")))

attr-str 也转义 "。)

您可以使用 @# 获取该函数'net.cgrand.enlive-html/xml-str (Clojure 并不倾向于使事情真正私有...)或者只是将其复制到您自己的命名空间。

Update: I knew there had to be more than that...

ring.util.codec from ring-core has a functions called which work like so:

user> (require '[ring.util.codec :as c])
nil
user> (c/url-encode "<a>")
"%3Ca%3E"
user> (c/url-decode "<a>")
"<a>"

These are wrappers around java.net.URLEncoder and java.net.URLDecoder. The same namespace provides functions for dealing with Base64 encoding, based on a class from Apache Commons.


Original answer follows.

I'm not sure whether there is a public function to do this, but Enlive has two private functions called xml-str and attr-str which do this:

(defn- xml-str
 "Like clojure.core/str but escapes < > and &."
 [x]
  (-> x str (.replace "&" "&") (.replace "<" "<") (.replace ">" ">")))

(attr-str also escapes ".)

You could get at that function with @#'net.cgrand.enlive-html/xml-str (Clojure doesn't tend to make things really private...) or just copy it to your own namespace.

枯叶蝶 2024-09-09 22:15:44

事实证明,如果您使用 net.cgrand.enlive-html/content 将文本放入 HTML 元素,Enlive 默认情况下会转义 HTML。

(sniptest "<p class=\"c\"></p>" [:.c] (content "<script></script>"))
"<p class=\"c\"><script></script></p>"

It turns out Enlive does escape HTML by default if you use net.cgrand.enlive-html/content to put text into a HTML element.

(sniptest "<p class=\"c\"></p>" [:.c] (content "<script></script>"))
"<p class=\"c\"><script></script></p>"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文