コース目次 / 第1章
DOM XSS — 入力がコードになる瞬間
入力をinnerHTMLに渡すと、それはコードとして動きます。隔離枠の中で発火させ、textContentとの違いを見ます。
この章は攻撃の様子を見せます(自作環境専用)。動かすのは下の隔離サンドボックスの中の架空データだけです。ここで学ぶ技術を、自作環境・自分の許可環境・CTF の外にある相手に試してはいけません(法と倫理)。
XSS(クロスサイト・スクリプティング)は、Web でいちばん有名な壊れ方です。仕組みは一言で言えます——利用者の入力を、そのまま HTML として画面に埋め込んでしまう。すると、入力の中に紛れ込んだスクリプトが、他の利用者のブラウザで動きます。
法と倫理ゲート
手を動かす前に
このコースは攻撃の技術に触れます。実習してよい相手は、次の3つだけです。
- (a) 自分で作った練習用のやられ環境(このサイトが配る自作ターゲット)
- (b) あなた自身の許可された環境(自分の Thousand SKY・secret-notes-ctf など)
- (c) CTF 競技の中(規約の範囲で)
実在する第三者のシステムを許可なく触ることは、不正アクセス禁止法に触れます。 このゲートは、その線引きを毎回の入口で確かめるためのものです。詳しくは「セキュリティの法と倫理」へ。
同意すると、この先の内容が表示されます。
触ってみる
下はコメント欄をまねた練習場です。入力欄には、攻撃者のつもりで書いた文字列があらかじめ入っています。ボタンは2つ。同じ入力を、2通りの実装で下の枠に表示します。
- 「危ない実装(innerHTML)」を押すと、入力が HTML として解釈され、中に仕込まれた
<img>のonerrorが動きます。「攻撃者の JavaScript が実行されました」と枠が反応したはずです。これが XSS の発火です。 - 「安全な実装(textContent)」を押すと、同じ入力がただの文字として表示されます。
<img ...>という文字がそのまま見えるだけで、何も動きません。
何が違ったのか
差はコード1行です。
out.innerHTML = 入力 は、入力をHTMLとして解釈します。だからタグやイベント属性が生きて、コードが動きます。
out.textContent = 入力 は、入力をただの文字列として置くだけです。同じ <img> でも、画面には文字として出るだけで実行されません。
「DOM XSS」と呼ぶのは、この壊れ方がサーバではなくブラウザ側(DOM を操作する JavaScript)で起きるからです。サーバが正しくても、画面を組み立てる JS が入力を innerHTML に流し込めば、そこで発火します。
いま試したのは、自分で入力して自分の画面で発火させる形です(自己XSS。発火の仕組みそのものを見るためのものです)。実際の攻撃では、攻撃者の入力がサーバに保存されたり、URL から反射されたりして、それを開いた別の利用者の画面で同じことが起きます。冒頭で「他の利用者のブラウザで動く」と言ったのは、この配送があるからです。
持ち帰る一言
入力は、信じない。 画面に出すときは「文字として置く」(textContent)を既定にし、どうしても HTML を組み立てるならエスケープやサニタイズを通す。この一言が、XSS 対策の芯です。
次の章は、もう1つの「見えているのに信じてしまう」もの——JWT です。
こうなっていればOK
卒業まであと3章です。
この章はまだ完了していません。
保存できませんでした(プライベートブラウズ中かもしれません)。この端末に進捗は残りませんが、先へは進めます。