jQueryのhtml()によるクロスサイトスクリプティング

jQueryのhtml()によるクロスサイトスクリプティング

説明

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 = {'&':'&amp;', '<':'&lt;', '>':'&gt;', '"':'&quot;', "'":'&#39;'};
        return chars[tag] || tag;
    });
}
function showMessage(userInput) {
    $("#message").html(escapeHtml(userInput));
}

解説:

  • 変更前: 入力を直接 html() に渡すため、指定されたマークアップが解釈され、スクリプトを実行される可能性があります。
  • 変更後: text() で入力をテキストとして表示します。または、このHTML挿入位置に合わせて入力をエスケープし、マークアップとして解釈されることを防ぎます。

参考資料