TIL

同一オリジンとかSameSiteとかを完全に理解した

Webの世界は『同じサイトに対して〜』的な話が色々あって難しいので、ちょっとばかり完全に理解することにした。

同一オリジンとは

ブラウザから見た時のコンテンツの生成元をオリジンという。RFC 6454で定義されているらしい。

オリジンはスキーム(プロトコル)、ホスト(ドメイン)、ポートで定義される。

例えばhttp://gengogo5.com:8080なら、スキームは http でホストは gengogo5.com ポート番号は8080

この3つのどれかが異なるもの同士は同一オリジンとはみなされない。

なので次の4つは全部別のオリジンということになる。

  • http://gengogo5.com/
  • https://gengogo5.com/
  • https://sub.gengogo5.com/
  • https://gengogo5.com:8080/

サブドメインもホストが違うのでNG。紛らわしいけどサブディレクトリは同一オリジン。

オリジンが異なる場合にはCORSで制約を受けることがある。CORSに踏み込むと主題と逸れるので別の機会に復習することにする。

localhostと127.0.0.1は同一オリジンなのか

個人的に理解が怪しいと思っていた点がホスト。

http://localhost:80http://127.0.0.1:80は同一オリジンか?という話。

なんとなく直感的には同じようなイメージを持ちそうだけど、ホストが違うので同一オリジンではない。IPアドレスではなくてホストで区別している。

確かにlocalhost127.0.0.1にそれぞれリクエストしてみると、リクエストヘッダのHostの内容は異なっている。

curl -v http://localhost/
*   Trying 127.0.0.1:80...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.77.0
> Accept: */*
curl -v http://127.0.0.1/
*   Trying 127.0.0.1:80...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.77.0
> Accept: */*

teratailで同じ質問をされている方がいた。

https://teratail.com/questions/221492

よくよく考えれば、同一IPアドレスを同一オリジンとみなしてしまうと、DNSラウンドロビンだったりAレコードが変わった際に別オリジン扱いになるのでそれはそう、という気がする。

Cookieの送信先は同一オリジンなのか

Cookie の送信先についても、CORS と似てなんとなく『同じサイトは許す』的なイメージがあるが、CORSより厄介。

Cookieは後述する属性を考えない場合、発行元と同じドメインに対してのリクエストで送信される。サブドメインが異なる場合は送信されない。

ドメインが一致していれば送信されるということは、httphttpsでは混同されるし、ポート番号が違っても送信されることになる。従って『Cookieの送信先は同一オリジンではない』と考えるのが妥当そう。

また、ドメインの一致を見ているということは、IPアドレスを直指定してアクセスした場合はドメインが異なるため、Cookieが送信されないことになる。

Cookie送信先をゆるくしたり厳しくしたりする

『サブドメインとCookieを共有したい』とか、『特定のパスに対してのリクエストでだけCookie送信させたい』といったニーズに応えるために Domain 属性と Path 属性がある。

Domain 属性は Cookie の送信先の制限を緩和するもので、Set-Cookie時にDomain 属性でgengogo5.comが指定されたら、そのCookieはgengogo5.comだけでなくsub.gengogo5.comへのリクエストの時にも送信される。

Path 属性は Cookie の送信先をより制限するためのもので、Path属性に指定されたパス配下に対してのリクエストでのみ Cookie が送信される。サブディレクトリ配下も送信対象になるので、/が指定されていれば制限なしになる。

http 通信では送ってほしくない、というときには Secure 属性というのがある。

SameSite属性というもの

Cookie には SameSite 属性というやつもいる。

LaxStrictNoneの3択で、モダンブラウザと言われるブラウザたちの最新バージョンではLaxがデフォルト。

StrictはクロスサイトリクエストでのCookie送信を許さない。

Noneはクロスサイトリクエストをなんでも許す。

Laxはクロスサイトリクエストの一部でCookie送信を許さない。

Laxについては CSRF からの保護が主な目的なので、 POST メソッドでのクロスサイトリクエストでは Cookie が送信されない。じゃあ GET なら全部いいのかというと、top-level navigationという考え方があって、これに該当する GET なら良いらしい。top-level navigationはアドレスバーに表示されているURLが変わる画面遷移。逆にこれに該当しない GET とは?というと、インターネット広告表示がまさにこれ。うーん、難しい。

参考文献

https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy

https://datatracker.ietf.org/doc/html/rfc6265


このあたりの話で混乱しないためには、『同じサイト』とか『同じサーバ』といったふんわり理解ではなく、ドメインやオリジンなどそれぞれの用語の定義や、何をもって同一と判断するのかをおさえておくのが重要そう。


<< 記事一覧へ