■[OWASP ZAP2.4.3にあったバグ3]
出力にXSSがあっても、<html>~</html>の内部でないと自動診断で検出してくれない
本家GitHubのIssuesに(色々ダメな感じで)報告した
https://github.com/zaproxy/zaproxy/issues/2279
の解説です。
再現手順:
1) 以下のPOSTテスト用phpファイルを作成し、自己管理課のWEBサーバーに設置します。
[test.php]
<?php print_r($_GET); ?>
2) ブラウザのプロキシとしてZAPを設定し、1)で作成したファイルにURLパラメーター付きでアクセスします。
http://localhost/zaptest/test.php?param=123
URLパラメーターがページ内にダンプされる作りなので、例えば以下のURLにアクセスすれば、ブラウザ上でダイアログが立ち上がります(XSSフィルタが無効になっているブラウザで確認する必要があります)。
例)XSSサンプルURL:
http://localhost/zaptest/test.php?param=<script>alert(1)</script>
例)レスポンス:
HTTP/1.1 200 OK
Date: Sun, 12 Jun 2016 14:12:55 GMT
Server: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8
X-Powered-By: PHP/5.6.8
Content-Length: 51
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Array
(
[param] => <script>alert(1)</script>
)
例)ブラウザ(Firefox)でダイアログが表示:
このように、ブラウザ上でscriptタグが動作します。
このような単純なXSSは、ZAPによる自動診断で検出されるはずです。
3) 2)でZAPに記録された履歴に対し、右クリック-動的スキャンの設定で「URL Query String」に対し「クロスサイト・スクリプティング(反射型)」のみの動的スキャンをかけます。
今回のテスト用のphpには、上記で確認したような非常に単純なXSSがあるのですが、ZAPはこの場合XSSを検出しません。
なぜこれが検出されないのだろう? と思い、本家GitHubのIssueに報告を上げたところ、psiinon氏から以下のような回答が返ってきました。
https://github.com/zaproxy/zaproxy/issues/2279#issuecomment-190119827
要は、反射型、持続型のXSSルールはユーザー入力がHTMLの中に反映されることを分析するものなので、HTMLタグ内でないと検出されない、ということのようです。
また、「DOM XSS ruleだったら検出できると思う」という追加情報もいただきました。
それでpsiinon氏の言うようにユーザー入力が反映される個所をHTMLタグの中にしてみたところ、反射型XSSルールで検出されるようになりました。
[test.php]
<html><body><?php print_r($_GET);?></body></html>
また、当初の、HTMLタグの中にない場所でのXSSは、これもpsiinon氏の言うように、ZAPの「DOM XSS Active Scanner rule」で検出されることが確認できました。(「DOM XSS Active Scanner rule」は本記事執筆の2016/6/12時点でAlphaレベルのアドオンとなっています。)
ただ、これだと、現実問題としてスクリプトが動作するのに、<html>~</html>の中でないからということで、ZAPの標準のスキャンルールでは検出できないということになるので、診断漏れの危険があります。
これについては、開発メンバー間で多少の議論があったのち、Issueのタイトルが「- False Negative」が付いたものに変更されたりしたので、この場合の検出ルールをどうするか、今後検討されるのではないかと思われます。
本現象のZAP2.5.0での検証結果:
本現象はZAP2.5.0でも発生します。
続きます。