Create a gist now

Instantly share code, notes, and snippets.

CVE-2016-7401 CSRF protection bypass on a site with Google Analytics の解説

CVE-2016-7401

多くの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は削除されている。

検証方法

  1. referrerを変更してanalyticsを使っているサイトに遷移する
history.replaceState({},null,"/hoge,hoge=hoge");document.body.innerHTML='<a href="analyticsのトラッキングを使ってるサイト">click me</a>';
  1. 以下のようなcookieがanalyticsのjsからsetされる
... |utmcmd=referral|utmcct=/hoge,hoge=hoge"
  1. 伝統的な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すること自体は可能であるため、元々完全な保護にはなっていない。

sessionに保持しているtokenを送信する方式であれば、攻撃者はcsrf tokenかsession cookieを盗み出さないとCSRF攻撃が成立しない。

  • CSRF攻撃にcookieの読み取りが必要

他の言語やライブラリでの修正

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment