Hiccup を使うときはエスケープ問題にご注意
先日アドベントカレンダーで書いたといったドキュメントが思いの外好評ぽかったので安心しているところですが、一点だけ注意しないといけないことがあります。
とりあえず以下のようなコードを書いてみます。
(ns demo.core
(:require [hiccup.core :as h]
[immutant.web :as web]
[ring.util.response :as res]))
(defn handler [req]
(let [user-input "<script>alert('(\\\\( ⁰⊖⁰)/)')</script>"]
(-> [:div user-input]
h/html
res/response
(res/content-type "text/html; charset=utf-8"))))
(web/run #'handler {:port 3000})
するとあら不思議。
このようにアラートが画面に出てしまいます。これは Hiccup が自動的に文字列をエスケープしてくれないためです。ではどうしたら良いかというと次のようにします。
(defn handler [req]
(let [user-input "<script>alert('(\\\\( ⁰⊖⁰)/)')</script>"]
(-> [:div (h/h user-input)] ;; hiccup.core/h を使うことで文字列をエスケープすることが出来る
h/html
res/response
(res/content-type "text/html; charset=utf-8"))))
はい、これで安心ですね。
ホビー/学習用途で Hiccup を使う場合、そこまで気にする必要がないかもしれませんが実プロダクトで使うときには気を付けてください。
補足
自動的にエスケープしてくれるテンプレートエンジンが多い中、 Hiccup のような存在は珍しいと思います。この問題は Issue にもあがっているのですが、 Hiccup 自身を根幹から作り変えないと対応出来ない上に対応中のブランチも開発が止まっているようでなかなか改善されないでいます。
Hiccup のような記述方法は使いたいけど、いちいちエスケープをするのが嫌だ、という方は次のように Enlive を使うことで問題を解決できます。
<!doctype>
<html>
<body>
</body>
</html>
HTML のテンプレートを用意しておいて…
(ns demo.core
(:require [immutant.web :as web]
[net.cgrand.enlive-html :as html]
[ring.util.response :as res]))
(html/deftemplate layout "template/main.html" [content]
[:body] (html/content content))
(defn handler [req]
(let [user-input "<script>alert('(\\\\( ⁰⊖⁰)/)')</script>"]
(-> [:div user-input]
html/html
layout
res/response
(res/content-type "text/html; charset=utf-8"))))
こうすれば、 Hiccup の記述力を失わずにセキュアなコードを書くことができます。ベター Hiccup としても使える Enlive は優秀です。
(ドキュメントの方は後で注意書きを足しておきます)
Author And Source
この問題について(Hiccup を使うときはエスケープ問題にご注意), 我々は、より多くの情報をここで見つけました https://qiita.com/ayato_p/items/1cc68841861453cabd3e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .