読んでほしい方
・SameSiteヘッダーを指定するとCookieが送られなくなるんでしょ、でもどこへのリクエスト?あれCookieってなんだっけ、そもそもなんで?という方
・CRSFがウル覚えな方
この記事で学べること
・Browserは必ず送信先のドメイン用のCookieしかセットされない(リクエストできない)
・表現がややこしいが、遷移先が別ドメインでもCookieはセットされる。(当然言えば当然、その遷移先のドメインのCookieなんだから)
・(上の文からの続きで何が悪い、といいたいが、)これはCSRFの穴になる。
・だからSameSite属性で明確にBrowserの挙動を指定することができる、具体的にはlax, strict指定するとCookieが送られなくなります。つまり多くの場合、再ログインが必要になるかなw
では説明をはじめます。
これまでSameSiteのdefault valueはNoneでしたが、もうすぐリリースされるchrome80からはSameSite=Lax がdefault valueになります
ということでSameSiteってなになのか?
どういう影響があるのかみていきます。
こちらの記事はhttps://web.dev/samesite-cookies-explainedの説明を元にしています
まずはこれを理解するにはCookieの次の仕組みを理解している必要があります
例えばとあるblogサイトがありまして
広告が表示されたとします。あなたはその広告がいやで❌印でその広告を閉じたとします
これは俗にいうopt-outという
ユーザーが広告の表示の有無を指定できるような仕組みですね
この時、
`Set-Cookie opt_out=1; Max-Age=260000; Secure`
というhttp responseヘッダーがサーバーから送られていきていて
ちなみにこの意味はサーバーは、「クライアントさん、もし接続が安全(https)で,Cookieが260000秒(一ヶ月)以内の該当するCookie, opt_outがあれば送ってくだいね。」
というものです。
ユーザーはこれに対して、❌印をクリックすることで、
クライアント内(chrome browserとか)にcookieを発行することになります。発行timestampが保持されるので
ここから有効期限が把握できるわけですね。そして
リクエストを送る際にSet Cookieで指定されている条件を満たしているので(Secure;接続が安全でCookieが発行から1ヶ月以内)、http reuest ヘッダーにCookie: opt_out=1をセットしてリクエストすることになります
javascriptのconsole立ち上げて
document.cookieって適当なサイトで打ち込むとそのサイトにどんなcookieが発行されているか
確認できますよ。たとえばamazon.comでは
とすると
session-idやらlc-acbjp=じゃ_JPyara、だいたい10個くらいでてきますね。
これらが全てSet-Cookieの条件にあわせてリクエストされるんですねー
しかも、これjavascriptで簡単にオーバーライドできちゃいます
ここでone tip
サイトによっては10個くらいCookieがあるとおもいますが、これを毎リクエスト、httpヘッダーにするのって
大きい規模でみると相当な帯域の無駄なのでMax-age
を指定しましょうね
いくつかCookieにかんするチップを再度、まとめて書いておきましょう
Cookieてリクエスト毎に送られて、大きい規模でみると相当な帯域の無駄なのでMax-age
を指定しましょうね
first-party Cookieと
third-part Cookieとは
前者が現在みているサイトと同じドメインのcookieで、後者がそれ以外のCookieです。
ですから、example.comにとってのother.comはthird-party Cookieですが、other.comにとってother.comはfirst-parth Cookie ですw
ここまではわかるのですが
さらっとサードパーティーのcookieがどういう条件の時におくられるのか
さっぱりよみとれません。
ほかの記事もあたって調べています。
なんか いいねボタンを含むようなサイトはあやしいのでみてみます。
余談だがいいねボタンは個人情報がfacebookに吸われるが個人データ保護の責任は埋め込みサイトにもあるとされたようだ
とはいっても
ここの仕組みがまだ理解できていない。なぜならもちろん
以下のnaverまとめサイトの場合、イイネボタンがあるが、これを押した時に送信されるnaverの情報といえば
referrerくらいのものだ。cookieはおくられているが、これらはfacebook専用のものにおもう。
もちろんnaverのサイトの通信でもやりとりされるのはnaverのcookieだけに思う。
調査をすすめる
この記事How 3rd party cookies are set: step by stepを理解するのが早そうだ
brwoserは現在みているdomain以外のCookieは絶対にアクセスできないので
3rd party cookiを利用するには、iframeを利用するしかないようだ。
iframeしかないような言い方をしているが、覚えやすように言っているだけでそうではない、
要はとあるページから別のサイトにアクセスできれば何でもいいのだ、とうのが今の理解だ
例えば<img> <src>などでもよい。ただしajaxコールはドメインの制約が合ったはずなので
そこを調べてほしい。
ではここでは、cookieを利用して、別サイトに情報が溜まっていく様子を見てほしい。
全部見れば理解できる思うが3rd partyを1st partyに直接おるすべはないといこと、意味している。
百聞は一見にしかず、
①まず、browserからFirst.comというサイトにアクセスする。すると②htmlページに返される、そこにはimgでThird.comから画像をとってくるような記述がある
①Browser --------------------------------> First.com (1st Party)
②Browser <------------------------------- First.com (1st Party)
<img src=http://thrid.com />
Set-Cookie id=123
この時点でクライントであるBrowserはSet Cookieの指示に従い、first.comというドメイン空間に
id=123というCookieを登録または更新する
つぎに
③<imgタグで設定されていたthrid.comにリクエストが飛びます。
ただし、この時に1st party, first.comに登録されたCookieがリクエストされること
はありません。そうするとbrowserの設計に反します。samesite explained記事によるとあたかも
1st party cookieが3rd party serverに送信されるように書かれていますがそんなことはないはずです。
現に図の解説をみても、そのようにはなっていません。
④画像リクエストにたいするレスポンスとして返却されたレスポンスにSet-Cookieがまた入ってきています。これはthird.comにおけるこのユーザー情報かなにかでしょう。
③Browser --------------------------------> Third.com (3rd Party)
④Browser <------------------------------- Third.com (3rd Party)
Set-Cookie id=987
すると
(pointX)この時点でクライントであるBrowserはSet Cookieの指示に従い、third.comというドメイン空間に
id=987というCookieを登録または更新する
そして特筆すべきなのは、今third.comというサーバー内にはid=987というユーザーはfirst.comというサーバーからリクエストしてきたので「first.comというサイトを訪問したことがある」という情報が
記録されます。
Third.com内情報: id=987 visitted sites are first.com
さて、これを別のサイトでも行った様子を追っていきましょう
今度はfirst.comではなくてdaiichi.comとしましょうか
ただし要領は同じです。
⑤Browser --------------------------------> Daiichi.com (1st Party)
⑥Browser <------------------------------- Daiichi.com (1st Party)
<img src=http://thrid.com />
Set-Cookie id=3456
当然、別々のサイトなので振られているidは違います。
ここではid=3456をセットしてね、とあるのでブラウザーは指示にしたがいます。
daiichi.comというドメイン空間にid=3456というCookieを登録または更新する
一回目と同じように返却されてあhtmlにはimgタグでthrid.comへの画像リンクが埋め込まれています
ので、同様にリクエストが飛びます。
ただし、繰り返しになります、この時に1st party, daiichi.comに登録されたCookieがthird.comサーバーへのこの画像リクエストに乗ることはありません。
⑥画像リクエストにたいするレスポンスとして返却されたレスポンスにSet-Cookieがまた入ってきています。これはthird.comにおけるこのユーザー情報かなにかでしょう。
最後に
(pointX)この時点でクライントであるBrowserはSet Cookieの指示に従い、third.comというドメイン空間に
id=987というCookieを登録または更新する
そして特筆すべきなのは、今third.comというサーバー内にはid=987というユーザーは今度はdaiichi.comというサーバーからリクエストしてきたので「daiichi.comというサイトを訪問したことがある」という情報が記録されます。
Third.com内情報: id=987 visitted sites are first.com, daiichi.com
繰り返しになりますが、
あーー
そうか、結局ブラウザーが違うドメインのつまりは3rd party cookieを送ることはブラウザーの使用上不可能です
しかし、pixelとかiframeとかを使って、3rd partyへとリクエストが送信される度に、3rd partyのサーバー側で新たに、refferredからどのユーザーがどのwebサイトを
利用したかとう行動履歴は貯めることができます。つまりはpixelを埋めた外部サイトにおける行動履歴が取れる、把握できる
ちゅうことにつながります。
結局、オンライン広告会社はこの情報が欲しいのです
このユーザーはこんなサイトを最近、転々としているのがわかりました
それぞれのサイトの扱っている商品はこれこれあれあれだから
今、このユーザーが興味をみっているのはこれこれにちがいない。
だから我が社(オンライン広告会社)のストックからこの広告を表示しよう!
と
なるし
そうするための仕組みです。
ではどうすればオンライン広告会社は
いろんなサイトにこのpixelやiframeをおいてもらうことができるのでしょうか?
それはもちろん、それを設置するメリットをクライアントにあたえないといけません。
facebookであればいいねボタンを設置すると集客が増えるだとか
アフェリエイト(まさにオンライン広告)だと、広告収入の一部を利益として払うとか
のような
機能的な魅力か金銭的な魅力のどちらかを訴求している
のだな
とわかりました。
さて話はSameSiteヘッダーに戻ります。
ここまでCookieと3rdパーティーサーバーとの絡みを見てきて
どうやらPointXにおいての話かもしれない とおもってきました。
first.comを訪問中に確かに画像リクエストでthird.comに言ってきたけれでも
この時にthird.comのCookieをBrowserに書き込んでくれるな!というような指示をするのが
このSameSiteの役割ではなかろうか!?
それならば合点がいく。
どれどれ
と前につまみ食い気味に別ブログでSameSiteが解説されているのでそちらを読んだところ
ここでは3rd partyのCookieは普通に送信されちゃうのがdefaultの挙動だぞ!
と書いてある。これは上で散々わたしが否定してきた、ブラウザーの設計として自分のドメイン以外のCookieは決して送信しないとう発言を全否定するものである。
確かめなければ
。
しかし。そんなサイト、見つけられるだろうか、サイトにべつリンクがあってそのリンク遷移時に1st partyのcookieがおくられちゃう。
そもそも、そんな設計よくないよな。
と思いながら執筆・調査をつづける
そしてこの記事Cookie の性質を利用した攻撃と Same Site Cookie の効果がわたしの最初の発言を肯定してくれた結果となりました。
引用になりますが
Cookie は、 Set-Cookie によって提供したドメインと紐づけてブラウザに保存され、同じドメインへのリクエストに自動的に付与される。
最も使われる場面は、ユーザの識別子となるランダムな値を SessionID として付与し、その有無によってセッション(=ログイン状態)を維持するという用途だろう。
もし SessionID が盗まれれば成りすましが可能となるため、セキュリティのコンテキストでは Cookie 自体が Credential として扱われることもある。
そして今回注目するのは、 Cookie が「ドメインをまたぐリクエストにも自動で付与される」という挙動だ。
(quoted from https://blog.jxck.io/entries/2018-10-26/same-site-cookie.html)
かなりわかりやすくCSRFと合わせて説明されているので是非参考にしてみてください
で、
大事な部分ですが、やはり、ブラウザーは3rd partyのCookieを送ることはありません(キッパリ)
しかし、1st parthのhtmlの中から別の3rd partyへ遷移する時に、Cookieは付与されます。この時付与されるのは当然遷移先のドメイン用のCookieです。
これをCookie が「ドメインをまたぐリクエストにも自動で付与される」という挙動、といっています。
最後におまけでlax, strictの違い
strictはcross-site, 3rd-partyへの通信に対しての全リクエストに対してCookieの付与を認めません。
laxはすこしゆるくてGETメソッドはまぁ、いいですよ。という内容です。
HTML | lax | strict |
<a href="http://foobar.com/"> | ⭕ | ✖ |
<form method="get" action="http://foobar.com/" > | ⭕ | ✖ |
<form method="post" action="http://foobar.com/" > | ✖ | ✖ |
<img src="http://foobar.com/img.png"> | ✖ | ✖ |
<iframe src="http://foobar.com/"> | ✖ | ✖ |
ajax.get('http://foobar.com/') | ✖ | ✖ |
ということでまとめ
・Browserは必ず送信先のドメイン用のCookieしかセットされない(リクエストできない)
・表現がややこしいが、遷移先が別ドメインでもCookieはセットされる。(当然言えば当然、その遷移先のドメインのCookieなんだから)
・(上の文からの続きで何が悪い、といいたいが、)これはCSRFの穴になる。
・だからSameSite属性で明確にBrowserの挙動を指定することができる、具体的にはlax, strict指定するとCookieが送られなくなります。つまり多くの場合、再ログインが必要になるかなw
以上です
参考資料
https://web.dev/samesite-cookies-explained
https://www.chromestatus.com/feature/5088147346030592
Cookie の性質を利用した攻撃と Same Site Cookie の効果