14

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

这个堆栈中是否有函数可以剥离 HTML 或 HTML 编码(即<a>&lt;a&gt;用户提供的字符串以防止 XSS 攻击?

4

3 回答 3

19

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

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

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

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

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

当然,还有很多用于此的 Java 库。您可以使用来自 Apache Commons 的StringEscapeUtils :

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

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

于 2010-05-24T16:35:03.837 回答
15

更新:我知道必须有更多...

ring.util.codecfromring-core有一个名为的函数,其工作方式如下:

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 "&" "&amp;") (.replace "<" "&lt;") (.replace ">" "&gt;")))

attr-str也逃脱了"。)

您可以使用@#'net.cgrand.enlive-html/xml-str(Clojure 不会使事情变得真正私有......)来获得该功能,或者只是将其复制到您自己的名称空间。

于 2010-05-24T14:21:57.277 回答
4

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

(sniptest "<p class=\"c\"></p>" [:.c] (content "<script></script>"))
"<p class=\"c\">&lt;script&gt;&lt;/script&gt;</p>"
于 2010-05-25T09:54:09.273 回答