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

时间:2010-05-24 14:12:10

标签: clojure xss compojure

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

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

3 个答案:

答案 0 :(得分:18)

hiccup中的

hiccup.util/escape-html就可以了。该函数曾经在Compojure本身(因为打嗝中的所有功能都曾是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的地图 - &gt;字符串转义序列和字符串并为您转义。

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)

尽管如此,这让我觉得有点重量级。

答案 1 :(得分:15)

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

来自ring.util.codec

ring-core有一个函数,其工作原理如下:

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

这些是java.net.URLEncoderjava.net.URLDecoder周围的包装。基于Apache Commons的类,相同的命名空间提供了处理Base64编码的功能。


原始答案如下。

我不确定是否有公共函数可以执行此操作,但Enlive有两个名为xml-strattr-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不会让事情真的私有......)或者只是将它复制到你自己的命名空间。

答案 2 :(得分:4)

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

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