Jeremiah GrossmanのBlogに、Preventing CSRF when vulnerable to XSSという記事がありました。
MySpaceワームなどを念頭に、XSS脆弱性がある状態でCSRFを防ぐアイディアを記述しています(現時点ではあくまでも実験的な内容だと、冒頭に注意書きされています)。
手法は、XMLHttpRequest、window.open、iframeという、JavaScript Wormの3点セットを、関数の上書きなどにより使えなくするというものです。
// XMLHttpRequest function XMLHttpRequest() { } // window.open window.__defineGetter__("open", function() { }); // iframe document.__defineGetter__("write", function() { }); document.createElement = function () {}
面白いアプローチです。しかし、(ご本人も判った上でしょうが)この種のhackには限界を感じてしまいます。実際、iframeに関しては「innerHTMLがあるぜ」という突込みが早速入っています。
私が考えるところ、Web AP側でできる対策としては、
1. パスワードの再入力
2. XSSリスクの高いページのドメインを隔離
くらいだと思います。
1は、攻撃者がXSSを突いて、もっともらしいログイン画面を偽造し、被害者がパスワードを入力してしまったらアウトです。しかし、そうなればCSRFどころの話ではありません。
2は、はてなのようなサービスで言えば、XSSリスクが高い日記を閲覧するページと、編集ページのドメインを別にすることです(認証用cookieも別にすべきです)。そうすれば、閲覧ページにXSSがあっても、編集ページのCSRF防止用のトークンを奪えません。もちろん、編集ページのドメインにXSS脆弱性があればアウトなので、完全な方法ではありませんが、リスクは減らせるはずです*1。
*1:拙文「よりセキュアなWebサイト構築 - 4.7 JavaScriptの除去」に書いてます。高木さんもどこかで同じことを書いていました。そういう対策が世間で余り語られないのは不思議です。