2025/08/08 22:42 How to safely escape JSON inside HTML SCRIPT elements

やあ、ロボ子!今日はscriptタグについて話すのじゃ。

scriptタグですか。HTMLにJavaScriptを埋め込む際に使うものですね。

そうじゃ!でも、このscriptタグ、意外と曲者なのじゃ。HTMLエスケープが不要で、どんな言語やデータも入れられるから、特別な解析ルールがあるんじゃ。

特別な解析ルール、ですか?

例えば、scriptタグの中に`</script>`があると、ブラウザが勘違いして、途中でscript要素を閉じちゃうことがあるんじゃ。

それは困りますね。`json_encode()`を使っても、問題が起こる可能性があると記事に書いてありますね。

そうなんじゃ。`json_encode()`も万能ではないんじゃな。HTMLのscriptタグの解析には、「script data double escaped state」という複雑な状態があって、これが予期せぬ動作を引き起こす原因になるんじゃ。

script data double escaped state...初めて聞きました。

この状態を避けるためには、`<`文字をエスケープする必要があるんじゃ。HTML標準では、`<`を`\x3C`、`<!--`を`\x3C!--`、`<script`を`\x3Cscript`、`</script`を`\x3C/script`としてエスケープすることが推奨されてるぞ。

なるほど。`<`をエスケープするんですね。

PHPなら、`JSON_HEX_TAG`フラグを使うと、すべての`<`と`>`が`\u003C`と`\u003E`に変換されるんじゃ。

`JSON_HEX_TAG`ですね。覚えておきます。

PHPでJSONをscriptタグに出力する際には、`JSON_HEX_TAG`と`JSON_UNESCAPED_SLASHES`フラグを使うのがおすすめじゃ。UTF-8を使っている場合は、`JSON_UNESCAPED_UNICODE`と`JSON_UNESCAPED_LINE_TERMINATORS`フラグも追加できるぞ。

フラグがたくさんありますね。状況に応じて使い分ける必要があるんですね。

そうじゃ!JavaScriptのソーステキストをエスケープする場合も、`<`をエスケープして、`</script>`でscriptタグが途中で閉じないようにする必要があるんじゃ。

了解しました。scriptタグ、奥が深いですね。

じゃろ?ちなみに、ロボ子がエスケープに失敗したら、私はロボ子の頭を…えーと、冗談じゃ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。