反射型XSSとは
反射型XSSの分かりやすい例として、徳丸本より引用したコードが以下になります。
<?php
session_start();
// ログインチェック(略)
?>
<body>
検索キーワード:<?php echo $_GET['keyword']; ?><br>
以下略
</body>
上記URLに対して、攻撃者は以下のようなリンクを用意し、被害者に踏ませることで攻撃が成立します。
http://example.jp/search.php?keyword=<script>alert(document.cookie)</script>
このように、XSSのサンプルとして挙げられるのはほとんどがGETをベースにしています。
クエリストリング付きのURLというシンプルな罠なので、分かりやすいからでしょう。次にPOSTベースのXSSについて考えてみます。
POSTのXSSについて
POSTのレスポンスにXSSが存在した場合を考えてみます。上記でいう$_GETが$_POSTになったようなイメージです。
GETではないので、以下のようなフォームを攻撃者が用意したとします。このコードはWikipediaを参考にしています。
<form action="http://example.jp/xxx.php" method="POST" name="trap">
<input type="hidden" name="keyword" value='<script>(悪意のあるスクリプト)</script>'>
</form>
<script>document.trap.submit()</script>
上記のフォームの送信先xxx.phpが、例えば「お問い合わせフォーム」の「確認画面」だとすると、XSS対策が漏れていた場合は当然ながらXSSが成立します。
よって、GETだろうがPOSTだろうが反射型XSSは成立するということで、メソッドによっての違いを意識する必要はないでしょう。
CSRFトークンはXSSを防げるのか
ここからが本題です。GET/POSTによる違いはXSSには存在しないと上述しましたが、そうではない場合があります。
POSTベースの処理には、クロスサイトリクエストフォージェリ(CSRF)の対策が施されている可能性があることです。
よくあるCSRF対策は、フォームを含んだGETレスポンスを返す際に、input要素としてhidden型のCSRFトークンを含んだフォームを返すことです。
つまり、先ほど例に挙げたフォームにはCSRFトークンが存在しない為、CSRFトークンの検証に失敗し、XSSは成立しないことになります。
このように、POSTベースのXSSの場合、CSRF対策によってXSSが成立する可能性が低くなるケースがあります。
“可能性が低い”と表現したのは、トークンの検証方法に問題がある場合などXSSが成立する余地があるからです。
CSRFトークンについて知りたい方は以下の記事を参考にしてください。
CSRFの基本的な対策とLaravelにおけるCSRF対策の実装について最後に、Burpの開発元の公式サイトから引用して締めたいと思います。
Some XSS attacks can indeed be prevented through effective use of CSRF tokens.
Assuming that the server properly validates the CSRF token, and rejects requests without a valid token, then the token does prevent exploitation of the XSS vulnerability. The clue here is in the name: “cross-site scripting”, at least in its reflected form, involves a cross-site request. By preventing an attacker from forging a cross-site request, the application prevents trivial exploitation of the XSS vulnerability.CSRFトークンを効果的に使用することで、実際にXSS攻撃を防ぐことができるものもあります。
XSS vs CSRF | PortSwigger
サーバがCSRFトークンを適切に検証し、有効なトークンのないリクエストを拒否すると仮定すると、トークンはXSS脆弱性の悪用を防ぎます。ここでのヒントは名前にあります。「クロスサイト・スクリプティング」は、少なくともその反映された形では、クロスサイト・リクエストを含みます。攻撃者がクロスサイト・リクエストを偽造するのを防ぐことによって、アプリケーションは XSS 脆弱性の些細な悪用を防ぎます。