document.domain
に関わる面白いSOPバイパスの手法を検証した。
document.domain
は古くからSOPを緩和するために使われてきたようだ。
例えば、同じ親ドメインを持つ2つのオリジン(例: foo.exapmle.com
とbar.example.com
)があり、SOPに縛られることなく互いに通信を行いたいとする。このとき、双方でdocument.domain
の値にexample.com
を設定することで、2つのドメインは互いのDOMにアクセスすることができるようになる。
今回検証したバイパス手法は、この挙動を利用したものである。
以下の条件を満たしているとき、SOPをバイパスできる。
まず、被害者のサイトに見立てて、以下のようなvictim.example.com
というページを用意する。
<!-- victim.example.com -->
<meta charset="utf-8">
<script>
console.log(document.domain);
document.domain = "example.com"; // vuln
console.log("document.domainの値は次のように設定されています。: " + document.domain);
document.write("このテキストはvictim.example.comに書かれたものです。");
</script>
このコードでは、5行目でdocument.domain = "example.com"
としている。
そのため、攻撃者の用意する以下のようなattacker.example.com
で同様にdocument.domain = "example.com"
とすると、攻撃者のページからもvictim.example.com
のDOMへのアクセスが可能になる。
攻撃の成立にはサブドメインのコンテンツを制御できる必要があるが、一般的な例ではSubdomain Takeoverでそれが可能になる。
<!-- attacker.example.com -->
<meta charset="utf-8">
<script>
console.log(document.domain);
document.domain = "example.com";
console.log("document.domainの値を次のように設定します。: " + document.domain);
</script>
<iframe src="http://victim.example.com/" onload="alert(contentDocument.body.innerHTML)"></iframe>
実際にattacker.example.com
にChromeでアクセスすると、victim.example.com
のページの内容をattacker.example.com
から取得できていることが確認できた。
検証では、attacker.example.com
からvictim.example.com
の内容を読み出せた。
もし、FacebookやTwitterなどに同じ問題(バグ)があった場合には、ユーザのメッセージやその他の情報を読み出される可能性がある。
また、document.domain
に最上位ドメインであるcom
やorg
などが設定されている場合には、victim.example.com
に対して、例えばevil.com
からの攻撃が可能になる。なお、現在はdocument.domain
に最上位ドメインを設定できる主要ブラウザはSafariのみで、その他の主要ブラウザではエラーになる。(詳細: [https://hackerone.com/reports/398163/])
上位ドメインを共有する2つのオリジンのdocument.domainに、共有している上位オリジンを設定すると双方のDOMにアクセスできるようになる。
これを利用して、問題のあるページのサブドメインのコンテンツをクライアント側で制御できるとき、SOPをバイパスしてそのページのコンテンツにアクセスすることが可能になる。また、サブドメインのコンテンツをクライアント側で制御できるようにする方法としてSubdomain Takeoverが挙げられるが、主要ブラウザの中でSafariのみはdocument.domain
にcom
やorg
などの最上位ドメインを設定できるため、Subdomain Takeoverが不要なケースがある。
このネタはTwitterで見かけたもので、検証が簡単だったので記事にしました。
(HackerOneで公開されたレポートは追うようにしているけど、今回の記事に関連するfiledescriptor氏のレポートは見落としてしまっていたなあ...。)
書き終わってから思ったのですが、2つのオリジンでdocument.domain
の値を変更して同一オリジンにしてるのを、SOPのバイパスと呼んで良いものか微妙ですね。
あと、Safariではdocument.domain
に最上位ドメインを設定できるってところ、実はMacを持っていないのでWindows版Safari(バージョン5.1.7)でしか検証できていません。
もし、最新版のMacで検証した人がいたら、結果を教えていただけたら幸いです。
Mac買いたいなあ...。