DOM based XSS について in Security.GS

2/19 に開催された Security.GS in 仙台 へ参加してきた。このイベントは、ゲヒルンの @isidai が全国のいくつかの箇所で行ったセキュリティ勉強会の一つ。そこでの主題がXSS、とくに最近増加しているという DOM based XSS についてだった。

 

参加してみて

既存のサーバ上で発生する XSS は認識していて、当然コーディングするときに気にかけてはいたけど、今回話題になった DOM based XSS は初めて聞いた。また、実際に innerHTML で DOM を生成するようなコードを過去に作ったことがあった。(APIを使う場合との違いがぱっと思いつかなかった、速度とかは若干思ったけど。)

今後自分でページを作るときに直接参考になる話だったし、出された例もわかりやすくて非常によかった。また、攻撃者の目線に関しては、私がセキュリティに疎いためにこれまで考えたことがなかったが、実際に目をつける点や、検証方法の一つを聴けたのも非常におもしろかった。

今回、会場の準備を手伝ったが、その際に協力していただいた 小泉さん(@koi_zoom1)、また会場を使用させてくださったアンデックスさんにはこの場で感謝の意を表したいと思う。

以下に簡単に内容を並べる。また、この勉強会のスライドは、今回の Security.GS めぐりが終わったのちに公開するとの話なので、正確な情報はそれを参考にしてほしい。また、ソースコードはたぶんそんなかんじ・・・(ぉぃ

 

@isidai が攻撃するなら...

まず、彼が攻撃するならまず何をチェックするか、という話が出た。

  1. HTTPレスポンスヘッダを確認する(使っている環境の情報や、初期設定から変更されているかがわかる。バージョンが脆弱性を含む古いバージョンであったり、設定がデフォルトのままのようなら楽に攻撃できるかも・・・?)
  2. htmlのソースを読む(入力値のチェックをJavaScriptで行ってサーバー側でチェックしていないと、不適切な値を送信できる。)
  3. サーバ上で解放されているポートを確認する(MySQLのポートとかさらされてたら・・・)
  4. サーバのレスポンス(ステータスコードとか)で中の挙動を推測する
  5. オープンリダイレクタ(リダイレクト先が可変になっているリダイレト)を探す
  6. robots.txt (管理画面とか見られたくないファイルのリストになっているかも!)
  7. sitemap.xmlWordpress等で自動生成させている場合、テスト用のコード等がいっしょに含まれている可能性が)
  8. phpmyadmin
  9. 直接 DOM 操作をせず、jQuery 等を用いて DOM 操作を行っていないか

この 9 番が、今回の主題、 DOM based XSS が可能である可能性を持っている。

また、実際に脆弱性検査を行う場合の実演を、 Burp suite を用いて行った。このアプリは、プロキシを立てて、ブラウザからのアクセスをこのプロキシを経由して行うことで、通信の細かい情報や、通信に手を加えたりできるもの。

具体的には、たとえば、GETリクエストがブラウザから発行されたら、まず、それをフックして、送信前に内容を表示する。このとき、送信するパラメータに変更を加えたりすることができる。そして、送信しようとおもったらアプリから送信ボタンを押すと、パケットが実際にサーバーに飛ぶようになっている。戻りも同様。

なにがいいかというと、まずさまざまなパラメータでの挙動確認が容易にできる。そして、一度行ったリクエストの中で、検証したいリクエストがあれば、アプリ上から連続してリクエスト送信が行えたりする。また、行われた通信から、そのサイトのファイル構造を可視化してくれたりもする。

XSS 概論

XSSには次の3パターンがある。

  1. 反射型
  2. 蓄積型
  3. DOM based XSS

最近、この DOM based XSS が増加している。

DOM based XSSとは

DOM based XSS とは、反射型、蓄積型の XSS とは異なり、サーバ側ではなく、ブラウザ側で発生するXSS

IPA からも 報告書が出ている(『DOM Based XSS』に関するレポート ~DOM Based XSSに関する脆弱性の届出が急増~

具体例1、innerHTML を用いてタグを生成している場合

たとえば、タグを次のような方法で生成している場合に生じる可能性がある。

 

 

この場合、もし、linkUrl が "><script>....</script> のようになっていた場合、任意の JavaScript の埋め込みが可能になってしまう。もちろん、Document.write() や jQuery の .html() でも同様だ。

 

 

このように、DOM API を用いてタグを生成してやれば、 script タグの埋め込みはできない。ただし、この場合も href に JavaScript がセットされる可能性には留意しなければならない。

具体例2、encodeURI によるURIエンコード

相対パスのリンクに対して、 encodeURI("/" + key) のようなコードを用意したとき、 key がもし、 / で始まった場合、いくつかのブラウザで勝手にプロトコルを補完して飛ばしてしまう。つまり、まったく違うドメインのサイトに飛ぶことになる。

対策として、encodeURIcompornents を用いるべきだ。

 

以上のように、 Ajax を用いたりしてブラウザ上でページを組み立てる場合は DOM based XSS に注意しなければならない。また、これらはブラウザ上で発生する XSS なので、 WAF (WebApplicationFirewall) は当然効力を発揮しない。