CVE-2016-7401
-
https://www.djangoproject.com/weblog/2016/sep/26/security-releases/
-
pythonのcookie parserが ; 以外もpairsの区切り文字として解釈するので、google analyticsのreferrer経由でsetされるcookieを使ってCSRF tokenを上書き可能だったという問題。
-
django側でcookie parser自前で実装、python本体は直ってないようだ https://github.com/django/django/commit/d1bc980db1c0fffd6d60677e62f70beadb9fe64a
多くのcookie parserは、pairsの区切りとして ; と , を許容しているのでdjango以外にも影響がある。 ブラウザが使用するcookie pairの区切りは実際には ;
CGI::Cookieでは "[;,] ?"
https://tools.ietf.org/html/rfc2965
Note: For backward compatibility, the separator in the Cookie header
is semi-colon (;) everywhere. A server SHOULD also accept comma (,)
as the separator between cookie-values for future compatibility.
https://tools.ietf.org/html/rfc6265 では、このNoteは削除されている。
- referrerを変更してanalyticsを使っているサイトに遷移する
history.replaceState({},null,"/hoge,hoge=hoge");document.body.innerHTML='<a href="analyticsのトラッキングを使ってるサイト">click me</a>';
- 以下のようなcookieがanalyticsのjsからsetされる
... |utmcmd=referral|utmcct=/hoge,hoge=hoge"
- 伝統的なCookie parserでparseする
hoge=hoge がkey, valueとして認識される。
RFC6265 以前に書かれたcookie parserは互換性のために , を許容していることが多いため、 cookieのvalueに限定的に任意の値をsetできるようなバグがあった場合に ; が使えなくても , が使えれば任意のkey,valueのsetが可能になっている。
cookie-valueには , は含まれないので , を含むvalueをsetしようとするのは本来は仕様違反だが、互換性のためにUAは受け入れるようになっている。RFC6265の実装ガイドでも , が含まれる場合にエラーにする処理はない。
- js,server: , を含むcookie valueのsetが必要な場合は、UAは受け入れてしまうので、何らかの方法でescapeするべき
- server: このような事情があるため [;,] を cookie pairsのdelimiterとして使用するのは、今では互換性よりもcookie上書きの弊害のほうが大きいと考えられるので、見直したほうが良い
djangoの事例は、Double submit cookie方式でのCSRF対策が突破されているが、そもそも攻撃者が用意したcsrf tokenの値を受け入れていることに問題がある。 HSTS includeSubdomains, preload を使わない限り、MITMでcookieを強制的にsetすること自体は可能であるため、元々完全な保護にはなっていない。
- https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Double_Submit_Cookie
- 送信されたcookieの値とformの値をcheckする方式、cookieの書き込みのみでCSRF攻撃が可能
sessionに保持しているtokenを送信する方式であれば、攻撃者はcsrf tokenかsession cookieを盗み出さないとCSRF攻撃が成立しない。
- CSRF攻撃にcookieの読み取りが必要