Hiccup을 사용할 때 이스케이프 문제에 유의하십시오.

7865 단어 Clojure
요 전날 어드벤트 캘린더로 썼습니다. 라고 하는 문서가 생각의 외호평 같았기 때문에 안심하고 있는 곳입니다만, 한점만 주의하지 않으면 안 되는 일이 있습니다.

우선 다음과 같은 코드를 작성해 보겠습니다.
(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 를 사용하는 것으로 문제를 해결할 수 있습니다.

resources/template/main.html
<!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의 기술력을 잃지 않고 안전한 코드를 작성할 수 있습니다. Better Hiccup으로도 사용할 수 있는 Enlive는 우수합니다.

(문서는 나중에주의 사항을 더해 둡니다)

좋은 웹페이지 즐겨찾기