Я использую стек Clojure/Ring/Compojure-0.4/Enlive для создания веб-приложения.
Есть ли функции в этом стеке, который или разделил бы HTML или HTML - кодируют (т.е. <a>
кому: <a>
) пользовательские предоставленные строки для предотвращения нападений на XSS?
Оказывается, Enlive делает escape HTML по умолчанию, если вы используете net.cgrand.enlive-html/content
для помещения текста в элемент HTML.
(sniptest "<p class=\"c\"></p>" [:.c] (content "<script></script>"))
"<p class=\"c\"><script></script></p>"
Обновление: Я знал, что должно быть что-то еще...
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.URLEncoder
и java.net.URLDecoder
. Это же пространство имен предоставляет функции для работы с кодировкой Base64, основанные на классе из Apache Commons.
Оригинальный ответ следует.
Я не уверен, существует ли публичная функция для этого, но 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 не склонен делать вещи действительно приватными...) или просто скопировать ее в свое пространство имен.
hiccup.util / escape-html
в hiccup делает это. Эта функция раньше была в самом 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
, который берет карту escape-последовательностей char -> string и строку и экранирует ее за вас.
user> (clojure.contrib.string/escape {\< "<" \> ">"} "<div>foo</div>")
"<div>foo</div>"
Это кажется мне не таким полезным, как могло бы быть, потому что вы можете захотеть избежать многосимвольных последовательностей, а это вам не позволит. Но это может сработать для ваших потребностей в экранировании HTML.
И, конечно же, для этого есть много Java-библиотек. Вы можете использовать StringEscapeUtils из Apache Commons:
(org.apache.commons.lang.StringEscapeUtils/escapeHtml4 some-string)
Это кажется мне немного тяжеловесным для этой цели.