#navi_header|技術| 今更ながらCSRFやCSSXSS関連の参考リンクをメモ。 - 開発者のための正しいCSRF対策 -- http://www.jumperz.net/texts/csrf.htm - 高木浩光@自宅の日記 - CSRF対策に「ワンタイムトークン」方式を推奨しない理由, hiddenパラメタは漏れやすいのか? -- http://takagi-hiromitsu.jp/diary/20060409.html - おさかなラボ - [CSRF]高木氏のエントリへの返答 -- http://kaede.to/~canada/doc/csrf-response-to-mr-takagi - CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例 - 徳丸浩の日記 -- http://www.tokumaru.org/d/20110127.html - なるほど:CSRF対策に「ワンタイムトークン」方式を推奨しない理由 -- http://blogs.wankuma.com/jitta/archive/2006/04/13/22414.aspx - CSRFとCSSXSSは分けて議論したい | 水無月ばけらのえび日記 -- http://bakera.jp/ebi/topic/2508 - こめんと(2006-03-30) : ■ [Security] えび日記: CSRFの説明に追記 -- http://www.oiwa.jp/~yutaka/tdiary/20060330.html - こめんと(2006-04-02) : ■ [Security] CSRF と CSSXSS に関する議論について -- http://www.oiwa.jp/~yutaka/tdiary/20060402.html - CSSXSSの問題 - adiary開発日誌 -- http://adiary.blog.abk.nu/090 - なぜCSSXSSに抜本的に対策をとることが難しいか -- http://blog.ishinao.net/2006/03/31/ #more|| 以下はmsakamoto-sfの個人的な考えです。 * CSRFの根っこ CSRFの根っことしては、正規画面遷移だけでなく、攻撃者が準備した不正な画面遷移(リクエスト)も受け付けてしまう点。 抜本的な対策としては高木浩光氏の日記にある図5のように、画面遷移を厳密に制御すると同時に攻撃者がリクエストを準備できないよう、推測が難しい値をリクエストに含める。厳密な画面制御を行う場合、識別に必要となるID値を推測の難しい値とすることで攻撃者によるリクエストの準備を難しくすることが出来る。 推測が難しい値 = "トークン" であり、固定トークン/ワンタイムトークンはCSRFの根っこにはあまり関係しない。 厳密な画面遷移制御は実装コストが高い。実装するのが難しい場合は、次善策としてトークン埋め込み+サーバ側でのチェックのみに留める。これにより攻撃者によるリクエストの準備を難しくする。 トークンの値に必要なポイント: - 推測が難しいこと。(時刻を元にした乱数などでは不十分。) - 外部に漏えいしないこと。(GETで渡すとRefererで漏えいする可能性があるので、POSTで送信する。) 「推測が難しいこと」について、自前でランダムな値を作ろうとするよりは、システムorWebプラットフォーム(ミドルウェアや開発言語)が提供しているランダムな値として「セッションID」を使用しても可。 但しトークンにセッションIDを使用する場合は以下の点を考慮: - アプリケーションの要求仕様(複数のブラウザウィンドウから同時操作された場合の挙動) - 途中のProxy等でキャッシュされてしまう事によるセッションIDの漏えい - CSSXSS等の脆弱性によっるセッションIDの漏えい 議論が迷走する地雷ポイント: - 固定トークンとワンタイムトークン - リロード対策(更新ボタン連続クリックや「二度押し対策」など) - CSSXSS対策 * 固定トークンとワンタイムトークン 推測が難しく漏えいしなければ、固定でもワンタイムでも、根っことしては問題ない。 ワンタイムトークンにより迷走するのは、リロード対策が関係してくるためと思われる。 固定トークンではリロード対策には成り得ない、という観点により、ワンタイムトークンを必要とする場合が考えられる。 但しCSRF対策によるトークンの導入とリロード対策とは分けて考えることが出来る。 なんとなればCSRF対策は固定トークンで実装し、リロード対策用に独立したワンタイムトークンを導入しても根っことしては問題ないはずである。 固定トークンにすることで推測される期間が広がる、という懸念もある。但し「推測が難しい値を推測される期間」に対する懸念としてはセッションIDも同様であり、少なくともセッションIDより短い有効期間にしておけば実用上は問題ないと思われる。もしそれでも不安であるならば、トークンよりも前にセッションIDが推測される方が懸念点として優先度が高いだろう。 * リロード対策 リロード対策もCSRF対策も、根っことしてはアプリケーションの画面遷移制御がポイントとなる。 CSRF対策はセキュリティの視点からの画面遷移に対する問題提起であり、リロード対策はユーザ操作という視点からの問題提起となる。 画面遷移の制御はアプリケーションの仕様の問題であり、リロード対策については「アプリケーションの仕様としてリロードによる二重POSTを許可するのか否か」という点から考える必要がある。 前述のようにCSRF対策用のトークンと、リロード対策用のトークンとを併用することも可能である。 アプリの仕様、CSRF対策、リロード対策等を考慮する時は論点の切り分けに注意が必要となる。 * CSSXSS対策 2006年のCSRF騒動に関連して話題となった、IE5-7のバグ。"@import"により、CSSとして解釈されうる外部サイトのコンテンツを読み込み、JavaScriptから参照可能だった。但し参照できる範囲はCSSとして解釈される範囲で、限定的。 これがCSRF対策と関連して語られる場合、CSRF対策のトークンも読み取られてしまうのでセッションIDをCSRF対策トークンとしてhiddenタグで埋め込む場合にCSSXSSのバグにより攻撃者の準備したJavaScriptからセッションIDを読み取られてしまうのではないか、という懸念点が問題となる。 特にトークンの値としてセッションIDを使用している場合、セッションIDの漏えいを懸念する場合がある。 CSSXSSに限らず、将来、同様に任意の外部ドメインのコンテンツに対してGETリクエストのレスポンスを、対象ドメインのCookieを送信することでログイン状態を維持したまま取得出来てしまう状況を想定してみる(例:XHRの実装ミスなどを想定)。 この場合、ブラウザがCookieを送信することにより攻撃者が被害者のアカウントでWebアプリケーションを操作して結果を取得できる点が根っことなる。つまり、そもそもセッションIDを盗まなくとも相当の自由度でログイン状態のコンテンツにアクセス可能な状態になる。POSTパラメータをGETでも受け付けるような作りになっていれば、アクセス可能な範囲はさらに広がる。 このような状況になると「HTMLコンテンツ中に埋め込まれることによるセッションIDの漏えい」を心配する以前の状況と考えられるが、セッションIDが明確に攻撃者に漏えいした場合、なりすましの被害がさらに発生する可能性があり、これを重要視する場合はトークンの値としてセッションID以外を使うべきだろう。 セッションIDを使い、なおかつCSSXSS対策を考慮するなら、おおいわ氏の2006-04-02の記事にあるとおり以下の対策を併用する。 - CSSXSSにより外部から読み取られたくない情報はPOSTリクエストのレスポンスのみに出力する。 - CSSXSSによりCSSとして解釈される範囲外に出力する #navi_footer|技術|