本サイトは、快適にご利用いただくためにクッキー(Cookie)を使用しております。
Cookieの使用に同意いただける場合は「同意する」ボタンを押してください。
なお本サイトのCookie使用については、「個人情報保護方針」をご覧ください。
MBSDでWebアプリケーション診断と教育を行っている山本です。
このトピックは昨年社外勉強会で発表させていただいたものをベースとしたものです。
概要
今回はWebブラウザの基本的なセキュリティ機構として広く知られている Same Origin と、Same Site について改めて紐解きます。これらには明確な違いがあり、Same Siteの働きについて適切な理解がないとクロスサイトリクエストフォージェリ(CSRF)をはじめとしたサイト間の攻撃の影響を受けやすくなります。特に、ドメインを第三者に貸し出すようなサービスではこの影響を強く受けるため、やっておくべきことと、ボランティアによってメンテナンスされているトップレベルドメインのリストの紹介をします。
Cross Site Request Forgeries (CSRF)
Cross Site Request Forgeries (クロスサイトリクエストフォージェリ、以下CSRF)は悪意のある攻撃者にリクエストを強制させられる事によって不利益を被る脆弱性です。代表的な被害例は、本人の意志とは関係なく掲示板に発言を投稿される、強制的な設定の変更などがあります。
以下のように、被害者は脆弱な掲示板サイトの利用者でログイン済みとします。
- 攻撃者は脆弱な掲示板サイトに悪意のある文章を投稿するように仕向けた罠ページを用意して被害者を誘導します。
- 被害者は掲示板にログイン済みですので、被害者のWebブラウザはセッションIDを悪意のある投稿とともに掲示板に送信します。
- 掲示板はセッションIDを参照し被害者名義で掲示板に悪意のある文章を投稿します。罠サイトから脆弱な掲示板サイトへの遷移はごく一瞬ですので、被害者本人の意志とは関係なく処理は完了してしまいます。
この脆弱性の対策でオーソドックスなものといえば、攻撃者が推測不能な「CSRFトークン」を生成し、掲示板投稿時に「CSRFトークン」を一緒に送信することです。Webアプリケーションは掲示板入力画面(ないしは確認画面など)で推測が困難なトークンを、ログインしているユーザに紐づけます。掲示板に投稿を実行する際にトークンも一緒に送信します。投稿を実行したユーザと、トークンに紐づいたユーザが一致すれば、本人によるリクエスト送信であることがわかるため、CSRFを対策することができます。
より詳しいCSRFについての内容は弊社ブログの別記事で解説しています。
そんなCSRFですが、SameSite Cookieという仕組みが登場したことで風向きが変わりました。
SameSite
通常、ユーザを識別するためのセッションIDが格納されたCookieは外部サイトから遷移する際にも送信されます。つまり全く別のサイトから、別のWebサービスに遷移してもCookieは送信されますから、ログイン状態が維持されます。そのため、CSRF攻撃を受けた際に罠サイトから遷移したときにCookieも送信され、ユーザを識別することができてしまいます。
SameSite CookieとはCookieに付与する属性値であり、設定内容に応じて外部サイトから遷移した際にCookie の送信を抑制する効果があります。すなわち、全く別のサイトから遷移するとCookieは送信されず、ユーザを識別することができないためCSRFをはじめサイト間の攻撃に対してある程度の耐性を持つようになります。
SameSiteには None, Lax, Strict の3種類から値を指定できます。None はSameSite の挙動を無効化する意味を持ちます。Strict は、異なるサイト同士の遷移ではCookieを一切送信しなくなります。仮にユーザ自信がWebメールに記載されたリンクを自分の意志でクリックしたとしても、異なるサイト同士ではCookieを送信しないので、遷移先のWebサイトでのセッションがリセットされます(ログイン状態が解除される)。Strict は大変厳しいルールを持っていますが、Lax はStrict を控えめな動作にしたオプションで、異なるサイト同士であっても、一部の遷移方法についてはCookie を送ります。Lax はユーザビリティの低下を最小限にできるので、実際多くのWebサイトで SameSite を適用する際は Lax の値が採用されます。
そんな SameSite Cookie ですが、近年は一部のウェブブラウザで Cookie のデフォルト動作を SameSite=Lax に設定した状態と同じ挙動になるよう、仕様を変更する動きがあります。つまり、仮にそのサイトでセッションとして使っている Cookie が SameSite の設定をしていなくても、SameSite 設定の恩恵を一部受けることができるということです。これにより CSRF攻撃の成功率が大きく下がると思われます。しかし、この仕様は一部ブラウザに限られますし、SameSite 設定のデフォルト値(=Lax)は一部のナビゲーションは制御の対象外であることからも根絶は難しいです。SameSiteのデフォルト設定によって不具合が出たWebサイトが、暫定対応として SameSite=None を設定するケースも見受けられます。そのため、 CSRF 脆弱性は設計・コードベースで作り込まないこと、脆弱性診断を行い発見次第修正することが依然として求められます。
加えて、限定的ですが自社のサブドメインを第三者に貸し出すサービスを提供している事業者が、適切な対応を行っていない場合、SameSite Cookie の効果を得られないケースがあります。これを理解するためには、Same"Site"である条件を見ていく必要があります。
Origin or Site
Origin
Webアプリ開発や、Webセキュリティを学習すると必ずと言っていいほど出てくる概念として、Same Origin Policyというものがあります。Same Origin Policy は、ウェブブラウザに実装されたWebページ間のリクエスト送信や操作についての基本的なセキュリティ機構であり、異なるオリジン間(Same Originではないページ同士)ではリソースのアクセスに制限が課されるようになります。
SameOrigin は
(スキーム) + (ホスト名) + (ポート)
の組み合わせで表すことができます。この組み合わせが完全に一致した2つのオリジンは、SameOriginとみなされます。反対に、少しでも異なる箇所があれば、SameOriginとはみなされません。
Origin A | Origin B | Is SameOrigin? |
https://www.mbsd.jp/news/ | https://www.mbsd.jp/advantage/ | YES |
https://www.mbsd.jp/news/ | http://www.mbsd.jp/news/ | No |
https://www.mbsd.jp/news/ | https://blog.mbsd.jp/news/ | No |
https://www.mbsd.jp/news/ | https://www.mbsd.jp:8080/news/ | No |
Site
SiteはOriginと似ているようで性質が異なります。端的に表すと、Siteは以下の要素の組み合わせで定義されます。※スキームフルの場合
(スキーム) + (eTLD+1)
この組み合わせが完全に一致した2つのサイトはSameSiteとみなせます。
Site A | Site B | Is SameSite? |
https://www.mbsd.jp/news/ | https://www.mbsd.jp/advantage/ | YES |
https://www.mbsd.jp/news/ | http://blog.mbsd.jp/news/ | No |
https://www.mbsd.jp/news/ | https://www.mbsd.co.jp/news/ | No |
https://www.mbsd.jp/news/ | https://www.mbsd.jp:8080/news/ | YES |
Originとは要素の組み合わせが違うことはわかりましたが、ここで出てくる eTLD+1とは何なのでしょうか。
eTLD+1とは?
TLD
それぞれの要素を分解して考えてみます。TLDとはTop Level Domain のことで、ドメインの最上位の階層を示します。
https://www.mbsd.jp の TLD は「jp」になります。ドメインの末尾の部分です。
TLD+1
+1とは、TLDに対して企業や個人が取得する部分です。
https://www.mbsd.jp の TLD+1 は「mbsd.jp」になります。mbsd 部分は jp レジストラから購入する必要がありますよね。つまり TLD と.(ドット)を一つ挟んだ文字列の部分を TLD+1 といいます。
ここで疑問が生まれます。 co.jp はどうなるのかという問題です。 co.jp は .(ドット)を一つ挟んだ文字列の部分がすべて含まれているので、 TLD が jp、 TLD+1 が co.jp であるように見えますが、coの部分は実際に個人や企業は取得することは出来ず、mbsd.co.jp のように .co.jp 以降の文字列を取得する必要があるので矛盾しそうです。
実際には、https://www.mbsd.co.jp の TLD は「co.jp」になり、TLD+1 は「mbsd.co.jp」になります。このように、ドメインの末尾だけでは判別が難しいケースがあります。現在流通しているブラウザがそのURLの TLD を判断するにはPublic Suffix List というリストを参照して、TLD を判定しています。
eTLD と Public Suffix List
eTLD とは、実質的にトップレベルドメインとして認識される部分のことを指します。先程例に出した、「co.jp」がそれに当たります。多くのブラウザやライブラリは「Public Suffix List」というリストを参照してそのドメインのトップレベルドメインを認識しています。
Public Suffix List はボランティアでメンテナンスされている「トップレベルドメインとして認識されるべきドメイン文字列のリスト」です。「co.jp」などもこのリストに掲載されています。このリストに掲載されているので、「mbsd.co.jp」はトップレベルドメインとして「jp」ではなく「co.jp」として認識されます。
Public Suffix List 追加申請
実は Public Suffix List はそのドメインの所有者で適切なプロセスを踏む事ができれば誰でも登録することができます。例えば、mbsd.jp そのものをトップレベルドメインとして扱うことも申請さえできれば可能です。
代表例として「github.io」があります。ioドメインはテクノロジー系のプロダクトに人気のドメインでしばしば見かけます。「github.io」 も、Github PagesというWebサイト公開機能で使われるドメインです。Githubでアカウント作成し、Github Pages のサービスを利用すると、「username.github.io」のようなドメインが無料で貸与されます。そしてその貸与ドメイン、実は「github.io」そのものがトップレベルドメインです。「co.jp」と同じ扱いになっています。実際にPublic Suffix Listに掲載されていることが確認できます。
github.io は人気のサービスだからeTLDとして扱うことで差別化を図っているのでしょうか?いいえ、クロスサイト攻撃からの対策の必要があり、github.ioを Public Suffix List に追加申請しているのです。
ドメイン貸し出しサービスにおけるクロスサイト攻撃
このような、サービス利用者(第三者)に自社のドメインを貸出すサービスを提供している組織では、貸出ドメインで Public Suffix List への追加が必要です。逆にいえばPublic Suffix List への追加申請を行わないとクロスサイト攻撃※1を受けやすくなるからです。
ここで復習です。このページの上部で説明した「SameSite」について思い出してください。SameSite属性はCookieに付与される属性であり、クロスサイトでのナビゲーション(画面遷移)においてCookieの送出をコントロールする属性でした。これを設定することにより攻撃者のサイトから、自社サイトへのCSRF攻撃を緩和することができます。攻撃者のサイトと、自社のサイトは「クロスサイト」だからです。Webブラウザはサイト同士のScheme と eTLD+1 が完全に一致しないと同じサイト(SameSite)として認識されません。
通常、eTLD+1が不特定多数によって運営されることはありません。ですが、ドメイン貸出を伴うサービスでは eTLD+1 が同一のかつ管理者が異なるサイトが存在しうるのです。
例えば、レンタルサーバを経営している会社があったとします。そこでは自分で決めた文字列を ◯◯◯◯.mbsd.jp という形で無料で利用できます。ここでは、shopping.mbsd.jp を取得したとします。このサービスは他にもユーザがいます。baseball.mbsd.jp , painter.mbsd.jp と貸出を行っていきます。
しかし、mbsd.jp はPublic Suffix List に申請をしていません。そのため、https://shopping.mbsd.jp のeTLD+1 は「mbsd.jp」になります。スキームさえ合致していれば、shopping.mbsd.jp、baseball.mbsd.jp、painter.mbsd.jp はすべて同じサイトという扱いになります。すなわち、CSRFへの耐性を高めるために設定した SameSite属性の効果がなくなってしまいます。ですから、攻撃者はターゲットのサイトへのCSRF攻撃を実現するために、無料で取得できるドメイン上で罠サイトを開設することが有効になります。
Github Pages では、github.io上で様々なWebコンテンツを設置できるので、SameSite属性の恩恵がなくなってしまいます。そのため、github.io をPublic Suffix List に登録することで、github.ioそのものをeTLDにする必要があるのです。上記の架空のレンタルサーバー会社も、mbsd.jp を Public Suffix List に登録すると、shopping.mbsd.jp の eTLD+1 は shopping.mbsd.jp となるため、SameSite属性の効果が得られるようになります。
ドメインをユーザに貸出し、コンテンツを提供できるサービスでは考慮しなければいけない問題になります。
さいごに
ドメインを貸し出すサービスは限定されるものの、Public Suffix List という仕組みは普段気にすることが少ないので見落とすケースは出てくると思っています。SameSite属性によってCSRFが成立するケースは少なくなる傾向にありますが、その恩恵を受けられない設計にならないよう仕組みの理解が大切ですね。
※1: CSRF以外にもCookieのdomain属性をサブドメインのサイトからTLD+1に対して設定することによるCookie Monster、Cookie Bombなどの攻撃が考えられますが、CookieのSameSite属性をメイントピックとさせていただいているためここでは割愛いたします。
免責:今回はSameSite属性にフォーカスして記述しています。それ以外の3rd party cookie の制限、Cookie isolationの仕組みなどの影響により記載した内容がそのまま再現できない可能性があります事ご注意ください。
山本 健太
おすすめ記事