説明
jQueryの html() は入力をHTMLとして解釈し、DOMへ挿入します。信頼できない内容を直接渡すと、クロスサイトスクリプティング(XSS)につながる可能性があります。攻撃者のマークアップが他のユーザーのブラウザーで動作し、セッションの悪用、なりすまし、フィッシングなどを引き起こすおそれがあります。
想定される影響
- スクリプトが読み取れるセッションCookieや機密情報が盗まれる可能性があります。
- ユーザーのブラウザーで悪意のあるスクリプトを実行されるおそれがあります。
- 画面を改ざんされ、偽のフォームなどのフィッシング内容を表示される可能性があります。
対処方法
- テキストの表示には、jQueryの
html()ではなくtext()を使ってください。 - テキストをHTML本文へ挿入する場合は、その文脈に合わせてエスケープしてください。実際のマークアップを許可する必要がある場合は、信頼できるHTMLサニタイザーでタグと属性を制限してください。
- 出力位置に合う処理を行ってください。HTMLエンコードはJavaScriptの処理やURL検証の代わりにはなりません。
例
変更前
javascript
// 入力をHTMLとして解釈
function showMessage(userInput) {
$("#message").html(userInput);
}
// <script>alert('XSS')</script> などの入力でスクリプトが実行される可能性があります。
変更後
以下はそれぞれ別の方法です。最初の方法はテキストとして表示し、次の方法はHTML本文へ挿入する文字列をエンコードします。
javascript
// 方法1: text()を使用
function showMessage(userInput) {
$("#message").text(userInput);
}
// 方法2: HTML用にエスケープ
function escapeHtml(str) {
return str.replace(/[&<>"']/g, function(tag) {
const chars = {'&':'&', '<':'<', '>':'>', '"':'"', "'":'''};
return chars[tag] || tag;
});
}
function showMessage(userInput) {
$("#message").html(escapeHtml(userInput));
}
解説:
- 変更前: 入力を直接
html()に渡すため、指定されたマークアップが解釈され、スクリプトを実行される可能性があります。 - 変更後:
text()で入力をテキストとして表示します。または、このHTML挿入位置に合わせて入力をエスケープし、マークアップとして解釈されることを防ぎます。