信頼できないデータをJavaScriptに挿入するときにXSSを回避するには、'
を'
に、>
を>
に、<
を<
に変換するだけで十分ですか?以下のような文字列?
<script>
param='payload';
</script>
上記の変換ではXSSを回避するには不十分な状況の例はありますか?
独自の「変換」ルールの使用に依存しないでください OWASP推奨 セキュリティに重点を置いたエンコーディングライブラリを使用して、必要なルールが適切に実装されていることを確認します。
次の文字をHTMLエンティティエンコーディングでエスケープして、スクリプト、スタイル、イベントハンドラなどの実行コンテキストに切り替わらないようにします。 XMLで重要な5文字(&、<、>、 "、 ')に加えて、HTMLエンティティを終了するのに役立つスラッシュが含まれています。
HTMLエンティティのエンコードは、
<div>
タグ内など、HTMLドキュメントの本文に挿入する信頼できないデータには適しています。ただし、「ネストされたコンテキスト」など、多くの場合には十分ではありません。<script>...param used directly here...</script> <!--...param used inside an HTML comment...--> <div ...param used in an attribute name=test /> <param as a tag name href="/test" /> <style>...param used directly in CSS...</style>
一般に、HTMLエンティティがエンコードされている場合でも、これらのネストされたエンティティ内ではparamを使用しないでください。
それだけでは不十分です。考案されたバックスラッシュの例:
<script>
var param1 = '{{ param1 }}'; var param2 = '{{ param2 }}';
</script>
param1=\¶m2=;alert(1)//
<script>
var param1 = '\'; var param2 = ';alert(1)//';
</script>
データがそのまま存続しないことは言うまでもありません。
<script>
var param1 = '<';
alert(param1); // Shows up as <, not <
</script>
改行(\r
、\n
、\u2028
、\u2029
)もJavaScript文字列を破壊する可能性がありますが、常に構文エラーであるため、脆弱性が作成されることはまれです。 。ユーザー入力をインライン<script>
インラインの変数に絶対に配置する必要がある場合は、JSONエンコードの後に</
を<\/
に置き換え、<!
を<\!
。ただし、最善の方法は、スクリプトの外部で信頼できるHTMLエンコーディングを使用することです。
<div id="my-information" data-something="{{ param1 }}"></div>
<script>
var param1 = document.getElementById('my-information').getAttribute('data-something');
</script>
動的スクリプトがないと、強力なCSPを実装できます。