DOM Based XSS のコード
Web ページに次の JavaScript が含まれている。攻撃者が利用者に https://www.example.com/top#%3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E という URL を開かせる攻撃に関する記述として,適切なものはどれか。
const msg = decodeURIComponent(location.hash.slice(1));
document.getElementById("notice").innerHTML = msg;- アWeb サーバで応答の HTML を生成する際に,リクエストのパラメータを HTML エスケープして出力するようにすれば,この攻撃は防げる。
- イセッション ID を格納する Cookie に HttpOnly 属性を付与すれば,挿入された img 要素の onerror 属性に書かれたスクリプトは実行されなくなる。
- ウ攻撃文字列はブラウザ上の JavaScript によって DOM に書き込まれるので,innerHTML ではなく textContent を用いて,文字列をテキストとして挿入するように修正する。
- エdecodeURIComponent は %3C などを < のような文字参照に変換するので,innerHTML に代入しても img 要素は生成されない。
正解と解説を見る
正解 ウ
この問題の基礎知識
- DOM Based XSS は,ブラウザ上の JavaScript が外部から与えられた値を DOM に書き込む処理で発生する XSS であり,サーバ側の処理を経由せずに起こり得る。
- URL のフラグメント(# 以降)はサーバに送信されず,ブラウザ上のスクリプトから location.hash で参照される。decodeURIComponent はパーセントエンコーディングを元の文字に戻す処理である。
- innerHTML に代入した文字列は HTML として解釈されるが,textContent に代入した文字列はテキストとして扱われ,タグやスクリプトとして解釈されない。
- Cookie の HttpOnly 属性は JavaScript からの Cookie の読取りを禁止するだけであり,挿入されたスクリプトの実行そのものは防がない。
URL のフラグメント(# 以降)は,リソースを取得する前に URI から切り離され,サーバには送信されない。スクリプトの挿入はブラウザ上の JavaScript の処理だけで起こるので,サーバ側のエスケープでは防げない。
HttpOnly 属性は,JavaScript から Cookie を読み取れなくするものであり,スクリプトの実行そのものは止めない。挿入されたスクリプトは実行され,Cookie の窃取以外の不正な操作は可能である。
location.hash の値を innerHTML に代入すると,文字列が HTML として解釈され,img 要素の onerror 属性のスクリプトが実行される(DOM Based XSS)。textContent は値をテキストとして扱うので,コードは実行されない。
decodeURIComponent は,パーセントエンコーディングされた文字を元の文字に戻す処理であり,%3C は「<」に戻る。HTML のエスケープとは逆に,タグとして解釈される文字列を作り出す。
照合の根拠(6 件)
- ア(誤り): フラグメントは取得の前に URI から切り離され,ユーザエージェントだけが扱うので,サーバ側のエスケープは効かない
the fragment identifier is separated from the rest of the URI prior to a dereference, and thus the identifying information within the fragment itself is dereferenced solely by the user agent, regardless of the URI scheme.
RFC 3986 · Section 3.5 Fragment(新しいタブで開きます) - ア(誤り)・ウ(正解): DOM Based XSS はクライアント側の処理が原因なので,データの流れに合った対策(クライアント側の出力方法)が必要
DOM-based XSS arises from unsafe client-side processing. In either case, the injected script executes in the browser; choose controls for the actual data flow and output context.
OWASP DOM based XSS Prevention Cheat Sheet · Introduction(新しいタブで開きます) - ウ(正解): innerHTML などの HTML として描画する属性に信頼できない入力を渡すと XSS になる
There are several methods and attributes which can be used to directly render HTML content within JavaScript. These methods constitute the HTML Subcontext within the Execution Context. If these methods are provided with untrusted input, then an XSS vulnerability could result.
OWASP DOM based XSS Prevention Cheat Sheet · RULE #1(新しいタブで開きます) - ウ(正解): innerHTML ではなく textContent を使うことが DOM Based XSS の修正方法である
The best way to fix DOM based cross-site scripting is to use the right output method (sink). For example if you want to use user input to write in a div tag element don't use innerHtml , instead use innerText or textContent .
OWASP DOM based XSS Prevention Cheat Sheet · RULE #7 - Fixing DOM Cross-site Scripting Vulnerabilities(新しいタブで開きます) - イ(誤り): HttpOnly はスクリプトから Cookie へのアクセスを禁じるだけで,スクリプトの実行は止めない
The HttpOnly cookie attribute instructs web browsers not to allow scripts (e.g. JavaScript or VBscript) an ability to access the cookies via the DOM document.cookie object.
OWASP Session Management Cheat Sheet · HttpOnly Attribute(新しいタブで開きます) - エ(誤り): %3C は 0x3C のオクテット(「<」)を表す表記であり,デコードすると「<」に戻る。文字参照 < にはならない
A percent-encoded octet is encoded as a character triplet, consisting of the percent character "%" followed by the two hexadecimal digits representing that octet's numeric value.
RFC 3986 · Section 2.1 Percent-Encoding(新しいタブで開きます)
URL の # 以降はサーバに送られず,location.hash を decodeURIComponent で戻した「<img src=x onerror=alert(1)>」が innerHTML で HTML として解釈されるので,ブラウザ内だけで完結する DOM Based XSS になる。html.spec.whatwg.org は 403 のため OWASP で代替。