ElmのXSS対策
Elmは非常に堅牢なアプリケーション開発に向いた親切でとても良くできた言語で、通常はXSS脆弱性を引き起こすことができないようになっています。
そのため、もちろん文字列として持っている生のHTMLを表示しようとして
import Html exposing (Html)
view : Model -> Html Msg
view model =
div
[]
[ text raw
]
raw : String
raw = """
<div>
こんにちはこんにちは
</div>
"""
このようにしても、実際には
<div>
<div>こんにちはこんにちは</div>
</div>
こういうHTML相当のものに変換されます。
生のHTMLを埋め込みたくなったら
じゃあ、生のHTMLをそのままHTMLとして埋め込みたくなったらどうしたらいいのでしょうか?
まず大前提として、生のHTMLは生肉と同じくらい危険です。
生肉なんてヤギでも食べません。
(草食動物だから)
生HTMLを表示したくなったら自分の設計を疑うべきです。
全然関係ないけど、アニサキスとサニタイズってなんか似てるよね。
それでもやりたい
Elm 0.18 であれば危険🐐スクリプト芸を使うことができましたが、あまりにも危険なので0.19では禁止されました。
Elm 0.19ではあきらめるしかないのでしょうか?
(再三いいますが、普通はあきらめて設計を見直したほうが良いと思います)
なんと、裏技があるのです。
Elmのアプリ内でコードをハイライト表示するでも使ったelm-explorations/markdownを使います。
これはもともとマークダウンのテキストを Elmの Html
型に変換する機能を提供しますが、その変換時に「HTMLをそのままサニタイズしないでHTML型に変換する」というオプションが用意されてます。
いぇーい。
それがOptions型の sanitize
っていうオプションです。
これを False
にして toHtmlWith
関数で Html
型に変換してやれば良いんです。
先ほどの例はこうなります。
import Html exposing (Html)
import Markdown exposing (defaultOptions)
view : Model -> Html Msg
view model =
Markdown.toHtmlWith
{ defaultOptions
| sanitize = False
}
[]
raw
raw : String
raw = """
<div>
こんにちはこんにちは
</div>
"""
わーい かんたん!