web-dev-qa-db-ja.com

出力がHTMLではなくJSに直接送られる場合、XSSから保護する適切な方法は?

出力が直接HTMLに送られる場合は多くの例が表示されますが、出力が直接JSに送られる場合は競合する情報が多く表示されます。

たとえば、コードが次の場合:

var thisIsATest = '<?php echo $_GET['a']; ?>';

そして、URL攻撃ベクトルは次のとおりです。

?a=';alert(1);'

出力は次のようにレンダリングされます。

var thisIsATest = '';alert(1);'';

回避すべきことを推奨する多くのドキュメント(addlashesなど)とhtmlspecialchars()への参照(単独ではない)を見てきました...

最も正しいアプローチは何ですか?

9
Jason Vendryes

正しい方法は、フレームワークのツール(および利用可能な場合はそのテンプレートエンジン)を使用することです。 JS文字列でPHPをいじっている場合、おそらく必要以上に人生をより困難で危険なものにするでしょう。

単純なPHPの場合、一般的で安全なアプローチは、説明したように json_encode() を使用することです here 。例:

_var foo = <?php echo json_encode($foo, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>
_

json_encode()は値のJSON表現を返すため、JSコードの有効なオブジェクトにエバレートされることが保証されており、図のように変数に割り当てることができます。 ただし、追加のフラグを省略しないでください。コンテキストによっては、攻撃者は_</script>_のようなペイロードを使用して、全体から抜け出すことができますスクリプトタグ。

あなたが参照した関数htmlentities()htmlspecialchars()は直接HTML出力に使用され、JSでは使用できません。また、文字列に改行を含めることができるため、セキュリティに影響を与える可能性のある構文エラーが発生します。

フレームワークについて言えば、Wordpressはラッパー wp_json_encode()このガイドライン で推奨されているように提供します。同等のものがあるかもしれません。独自のフレームワーク用の関数。

また、json_encode()を使用すると、オブジェクトはJSコンテキスト用に安全に準備されますが、渡す文字列には、たとえばdocument.write()またはを使用して挿入するのが安全でないHTMLタグが含まれている可能性があります。 innerHTML。 (これら2つは完全に避けてください。)

これはばかげていますが、XSSセーフです。

_Hello, <span id="display"></span>!
<?php $name = $_GET['name']; ?>
<script>
    var name = <?php echo json_encode($name, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>;
    display.textContent = name;
</script>
_
13
Arminius