LoginSignup
38
12

More than 3 years have passed since last update.

Elmで生のHTMLをそのまま表示させる

Posted at

ElmのXSS対策

Elmは非常に堅牢なアプリケーション開発に向いた親切でとても良くできた言語で、通常はXSS脆弱性を引き起こすことができないようになっています。
そのため、もちろん文字列として持っている生のHTMLを表示しようとして

import Html exposing (Html)


view : Model -> Html Msg
view model =
    div
        []
        [ text raw
        ]


raw : String
raw = """
    <div>
        こんにちはこんにちは
    </div>
    """

このようにしても、実際には

<div>
    &lt;div&gt;こんにちはこんにちは&lt;/div&gt;
</div>

こういうHTML相当のものに変換されます。

生のHTMLを埋め込みたくなったら

じゃあ、生のHTMLをそのままHTMLとして埋め込みたくなったらどうしたらいいのでしょうか?

まず大前提として、生のHTMLは生肉と同じくらい危険です。
生肉なんてヤギでも食べません。
(草食動物だから)

sakura.jpg

生HTMLを表示したくなったら自分の設計を疑うべきです。
全然関係ないけど、アニサキスとサニタイズってなんか似てるよね。

それでもやりたい

Elm 0.18 であれば危険🐐スクリプト芸を使うことができましたが、あまりにも危険なので0.19では禁止されました。
Elm 0.19ではあきらめるしかないのでしょうか?
(再三いいますが、普通はあきらめて設計を見直したほうが良いと思います)

なんと、裏技があるのです。
Elmのアプリ内でコードをハイライト表示するでも使ったelm-explorations/markdownを使います。
これはもともとマークダウンのテキストを Elmの Html型に変換する機能を提供しますが、その変換時に「HTMLをそのままサニタイズしないでHTML型に変換する」というオプションが用意されてます。
いぇーい。

sakura2.jpg

それが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>
    """

わーい かんたん!

さくらちゃんにご飯をあげる
さくらちゃんをもっと見る
他の記事を見る
end.jpg

38
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
12