はじめに
XSS(クロスサイトスクリプティング)攻撃を成功させるためには、単にスクリプトを注入するだけでは不十分です。注入したコードが「どこに配置されるか」という**コンテキスト(文脈)を理解し、必要に応じてセキュリティフィルターを回避(エベージョン)**する技術が求められます。
1. 実行コンテキストの重要性
攻撃ペイロードは、主に以下の3つの場所のいずれかに注入されます。場所に応じて、ペイロードの形式を適切に「脱出(エスケープ)」させる必要があります。
A. HTMLタグの間
最も単純なパターンです。
-
例:
<div>[ここに注入]</div> -
ペイロード:
<script>alert(document.cookie)</script> - 直接タグを書き込むだけで実行可能です。
B. HTMLタグの属性内
属性の中に注入する場合、まずはその属性やタグを「閉じる」必要があります。
-
例:
<input value="[ここに注入]"> -
ペイロード例:
"><script>alert(document.cookie)</script> -
">を使って既存のタグを強制終了させることで、後ろに続くスクリプトをブラウザに認識させます。
C. JavaScriptコード内
既存のスクリプトの中に注入する場合、現在の命令を壊さずに自分の命令を差し込む必要があります。
-
例:
var name = '[ここに注入]'; -
ペイロード例:
';alert(document.cookie)// -
'で文字列を閉じ、;で命令を終え、自分のコードを書いた後に//で残りのコードをコメントアウトしてエラーを防ぎます。あるいは、最初に</script>を置いてスクリプトブロック自体を終了させる手法も有効です。
2. フィルター回避(エベージョン)のテクニック
多くの現代的なアプリケーションには、特定のキーワードをブロックするフィルターが備わっています。これらを突破するために、攻撃者はさまざまな工夫を凝らします。
長さ制限の回避
入力フォームに文字数制限がある場合、Tiny XSS Payloads のような極限まで短縮されたコードが使用されます。
ブロックリストの回避(難読化)
特定の文字列(javascript: など)が禁止されている場合、特殊な文字コードを挿入して検知エンジンの目を欺く手法があります。
-
水平タブ (TAB):
	 -
改行 (LF):

 -
キャリッジリターン (CR):

例:javascript: という単語を分割する フィルターが「javascript:」を監視していても、以下のように記述することで検知を回避できる場合があります(ブラウザはこれらを無視して解釈します)。
<IMG SRC="jav	ascript:alert('XSS');"><IMG SRC="jav
ascript:alert('XSS');"><IMG SRC="jav
ascript:alert('XSS');">
まとめ:試行錯誤の重要性
XSS攻撃は一筋縄ではいきません。
- コンテキストの特定: 自分の入力がHTMLのどこに出力されているかを開発者ツールで確認する。
-
適切な脱出: クォーテーションやタグの閉じ(
>)を使って、実行環境を整える。 - 回避策の検討: フィルターに阻まれたら、文字コードの挿入や難読化を試す。
攻撃手法が数百通り存在するのと同様に、防御側も進化を続けています。これらを理解することは、より強固なコードを書くための第一歩となります。