PortSwigger Web Security Academy Writeup【XSS編①DOM-based XSS】
1. ご挨拶
はじめまして、タタラと申します。
今回はPortSwigger社が運営するlabs(脆弱性のPoCを行える環境)のうち、DOM-based XSSを扱ったラボを攻略したので、思考の過程を整理する目的で書いていきます。
実際のペイロードも記載しておりますので、ネタバレ注意でお願いします。
PortSwiggerのサイトはこちら(https://portswigger.net/)
2. 目次
- ご挨拶
- 目次
- DOM-based XSSとは
- ラボを攻略
4-1. 攻撃対象となる機能
4-2. 回答 - 関連するWeb API
- その他気になったこと、試したこと
- 参考文献
3. DOM-based XSSとは
DOM-based XSSとは、JavaScriptでDOM(Document Object Model)を操作する場合に発生しうる脆弱性です。Reflected XSSやStored XSSはサーバ側のプログラムの不備によって発生しますが、DOM-based XSSはフロントエンド側のプログラムの不備によって発生します。
4. ラボを攻略
4-1. 攻撃対象となる機能
今回攻略したラボはブログサイトを模した環境です。写真中のワード検索機能に脆弱性が存在します。
正常な値を入れて検索ボタンを押すと、上記の検索結果ページに遷移します。URLのクエリストリングに検索ワードが入れられています。
4-2. 回答
とりあえずXSS脆弱性の有無を検証する上で基本的なペイロード(alert関数)を入力してみましたが上手くいきませんでした。
そこで、検索ボタンを押下してから結果ページが表示されるまでに処理の流れを確認しました。
1.検索ワードを入力して検索ボタンを押下すると、'search'パラメータに検索ワードが入ったGetリクエストが発行されます。
2.検索結果ページをディベロッパツールで確認すると、パラメータ'search'に入った値を扱うインラインスクリプトを発見しました。
document.write()関数を用いてページ内に<img>タグを埋め込む処理と思われます。
入力値をGIF画像のソースパスの要素として用いているため、alert関数の前後にソースパスを指定するための'(セミコロン)や<img>タグを閉じる'>'を入れれば良さそうです。
よって
'"></script><script>alert(1)</script><script>'
をペイロードとして入力しました。すると...
alert関数が動作しました!このことから、このブログサイトでは攻撃者が任意のJavaScriptを実行可能であるとわかります。
このラボはこれにてクリアとなります。
Web Security Academyのページでは他の回答も紹介されているので、興味のある方はご覧ください。
(https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-document-write-sink)
5. 関連するWeb API
今回攻略したラボでは、ユーザの入力値をGIF画像のソースパスの一部として利用し、document.write関数でHTML内に<img>タグを埋め込み処理に脆弱性が存在しました。
このスクリプトで利用されているAPIについて、簡単にまとめておきます。
・URLSearchParams
クエリパラメータを操作する上で有用なメソッドを提供するAPI。
今回のスクリプトではget()メソッドでパラメータ'search'に対応する値を取得していました。
・window.location.search
windowインターフェースはDOMオブジェクトを収めるウィンドウを表します。
window.locationプロパティはスクリプトが実行されているファイルのlocationオブジェクトを返します。
window.location.searchプロパティはスクリプトが実行されているファイルのURLのクエリストリングを返します(?記号を含む)。
今回のスクリプトではURLから?search=ユーザの入力値
を抜き出していました。
・document.write()
document.open()
メソッドで開かれた文書にテキストの文字列を書き込むメソッド。
今回のスクリプトでは、ユーザの入力値を要素として作成したソースパスを含む<img>タグをファイル内に書き込む処理を行っていました。
6. その他気になったこと、試したこと
今回のラボで使われていたスクリプトを元に、ユーザの入力値を受け付けるページと入力値を表示するページを作成したところ、DOM-based XSSを再現できました。
<!DOCTYPE html>
<html>
<head>
<title>Form Page</title>
<meta charset="utf-8">
</head>
<body>
<h1>入力ページ</h1>
<p>ペイロードを入力</p>
<form action="./receive.html" id="form" method="Get" />
<input type="text" name="payload" required/>
<input type="submit" />
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>receive Page</title>
<meta charset="utf-8">
<script>
document.open()
let query = new URLSearchParams(window.location.search).get('payload')
document.write(query)
document.close()
</script>
</head>
<body>
<h1>入力データ受け取りページ</h1>
</body>
</html>
補足:
location.searchのようにDOM-based XSS脆弱性が生じる原因になりうる箇所を「ソース」、document.write()のようにユーザが入力したJavaScriptを実行してしまう箇所を「シンク」と呼びます。
今回は以上となります。ありがとうございました。
7.参考文献
- 「フロントエンド開発のためのセキュリティ入門」(平野昌士 著・2023年 翔泳社)
- MDN Web Docs (https://developer.mozilla.org/ja/)
- W3 schools (https://www.w3schools.com/)
Discussion