webブラウザセキュリティ
#ReadLog #プログラミング #2021.01
https://github.com/LambdaNote/support-browsersecurity.git
https://cdn.shopify.com/s/files/1/1634/7169/products/6268848537769-1_530x.png?v=1609803843
https://matsuand.github.io/docs.docker.jp.onthefly/compose/install/
ラボ環境の起動にdocker-composeが必要だったのでインストールした
mochi5o.iconWHATWGとかW3Cが読めないので調べた
Web Hypertext Application Technology Working Group(WHATWG、ワットワーキンググループ、ワットダブルジー)
World Wide Web Consortium 略称はW3C(ダブリュースリーシー)
序章〜1章
この本の全体の流れ。
なぜWebブラウザセキュリティが必要なのか、を掘り下げて考える。
Webを構成する基本の3つのコンポーネントの理解から、Webアプリケーションの動作に必要なクライアントサイドとサーバーサイドのシステムの構成要素についての解説。
セキュリティの観点からそれぞれの場所でどのようなことを考えなければならないかという総論があり、どの章で詳しく述べるかという本書のガイドになっている。
サーバーサイドWebシステムのセキュリティの関心事
システムの各構成要素をいかにセキュアにするか
またその各構成要素をいかにセキュアにつなげるか
クライアントサイドWebシステムのセキュリティの関心事
リソース感の論理的な隔離をどう達成するか
リソース感のプロセスレベルの隔離をどう達成するか
Cookieをどうセキュアに取り扱うか
出入りするリソースの信頼性をどう確保するか
2章
Originを境界とした基本的な機構
SOP(Same-Origin-Policy)について掘り下げて考える。
そもそもOriginとは??(厳密には多少異なる)
スキーム、ホスト名、ポート番号という3つの値のセットをOriginと呼ぶ
上記をもとに、Same-Originとは、ある2つのWebリソースのOriginが一致していることをSame-Originという
mochi5o.iconこのあたりは明確に意識したことなかったので学びになった。
SOPのもとで、Cross-Originなリソースに対して、そもそもどのような操作に制限を設けるべきか?というところから確認していく。あるリソースAから別のリソースBに対する操作のうち、制限すべきケースは2つ考えられる。
ブラウザ内アクセス
ウィンドウの参照を利用したDOM操作
XMLHttpRequestやFetchAPIなどにより発行したリクエストの結果を読み出す操作など
ネットワーク越しのアクセス
HTTPリクエストの発行によるアクセスのうち、aタグやformタグなどの単純なリクエスト以外
Content-Typeヘッダを伴うリクエストやその他の特別なリクエストヘッダを付したリクエスト
制限しなくて良さそうなケース
リソースの埋め込み
imgタグやiframeなどであるページに別のリソースを埋め込んだ状態
リソースの埋め込み自体は単純なリクエストを発行して画面にレンダリングしているだけなのでそんなに脅威ではないと考えられる、とのこと
実際にサンプルコードを動かして、Same-Originとはなにを指すのかを調べる。そのうえでCross-Originなリソースへの、ネットワーク越しのアクセスとブラウザ内アクセスの挙動を確認する。
mochi5o.iconたしかに、特定のCross-Originのリソースの取得などが制限された。なるほどなー。結果は以下の通り。
OK Cross-Originなリソースのページ内の埋め込み
NG Cross-Originなリソースへのブラウザ内アクセス
OK Cross-Originなリソースへの単純なリクエスト(formタグからのリクエスト)
NG Cross-Originなリソースへの複雑なリクエスト(fetch()をつかったもの)
では、Cross-Originなリソースへのブラウザ内アクセスを許可したいときは??
例えば、同じ会社が開発した2つのWebサービスをつなげたい、とか
具体的にはサービスAからサービスBのAPIへGETリクエストを送って結果をサービスA側で活用したいとか
→Access-Content-Allow-Originヘッダーを付与して、その値にサービスAのOriginを表す文字列(ホスト名)指定すれば良い
すべてのOriginを許可するときは、*(アスタ)を文字列に指定する
mochi5o.iconXMLHttpRequest (XHR)とは
XMLHttpRequest (XHR) は、JavaScriptなどのウェブブラウザ搭載のスクリプト言語でサーバとのHTTP通信を行うための、組み込みオブジェクト(API)である。すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。
XMLHttpRequestを利用したWebアプリケーションは非常に多く存在し、例として、Google マップ、Facebookなどが挙げられる。 https://ja.wikipedia.org/wiki/XMLHttpRequest
https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
mochi5o.icon例で出てくるタグや関数が微妙にうろ覚えなのでちゃんと調べる
<iframe>
HTML のインラインフレーム要素 (<iframe>) は、入れ子になった閲覧コンテキストを表現し、現在の HTML ページに他のページを埋め込むことができます。
それぞれの閲覧コンテキストは、セッション履歴と文書を持ちます。他の閲覧コンテキストを埋め込んでいる閲覧コンテキストは、親閲覧コンテキストと呼ばれます。最上位の閲覧コンテキストは (親を持たないもの) は、通常はブラウザーのウィンドウで、 Window オブジェクトで表されます。 https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe
<embed>
HTML の <embed> 要素は、外部のコンテンツを文書中の指定された場所に埋め込みます。コンテンツは外部アプリケーションや、対話型コンテンツの他の出所 (ブラウザーのプラグインなど) によって提供されます。 https://developer.mozilla.org/ja/docs/Web/HTML/Element/embed
<object>
HTML の <object> 要素は、画像、内部の閲覧コンテキスト、プラグインによって扱われるリソースなどのように扱われる外部リソースを表現します。 https://developer.mozilla.org/ja/docs/Web/HTML/Element/object
document.domain
Document インターフェイスの domain プロパティは、同一オリジンポリシーで使用される現在の文書のオリジンのうち、ドメインの部分を取得または設定します。このプロパティが正常に設定されると、オリジンのポート番号の部分も null に設定されます。 https://developer.mozilla.org/ja/docs/Web/API/Document/domain
document.body.innerHTML
Element オブジェクトの innerHTML プロパティは、要素内の HTML または XML のマークアップを取得したり設定したりします。
innerHTML に値を設定すると、正確には何が起きるのでしょうか?これを行うと、ユーザーエージェントは以下のステップを追います。指定された値は (文書型に基づいて) HTML または XML として解釈され、新しい一連の要素の DOM ノードを表す DocumentFragment オブジェクトの中に結果が入れられます。
中身を置き換えようとしている要素が <template> 要素である場合は、 <template> 要素の content 属性を、ステップ1で生成された新しい DocumentFragment で置き換えます。その他の要素はすべて、要素の内容を新しい DocumentFragment のノードで置き換えます。 https://developer.mozilla.org/ja/docs/Web/API/Element/innerHTML
CORSのやっていること
CORSは特定の条件下においてCross-Originなリソースへのアクセスを許可する仕組み
ブラウザ内アクセスの場合(リソースAからリソースBへのアクセス)
リソースBからのレスポンスにAccess-Allow-Originヘッダが含まれる
Access-Allow-Originヘッダが*になっているか、もしくはAのOriginを表す文字列が記載されている
ネットワーク越しのアクセスの場合
OPTIONSヘッダを使ってプリフライトリクエストを飛ばす
この時に特別なヘッダーを一緒に送っている(リクエストメソッドの種類とヘッダーの種類を送っている)
プリフライトリクエストの結果返ってきたレスポンスと、先に送ったヘッダーの内容が一致していたらCross Originな通信がOKされる
XSS(Cross-Site Scripting)脆弱性
同一Origin内のリソースのやりとりに対して制約を与えないSOPの欠点をついて、同一Origin内でjs実行を引き起こせるようなContent Injection脆弱性のこと。
CSP(Content-Security-Policy)で許可されていないスクリプトの実行時
Content-Security-Policy: script-src 'self' http://example.com; frame-src 'self';
というCSPがヘッダーに含まれている
https://gyazo.com/d9fb6f19c940c9c6ebd15d578019c35e
4章 Cookieに関連した機構
Cookieの属性
実際にScrapboxのページを見ながらSet-Cookieを見てみた
code:cookie
Set-Cookie: connect.sid=ランダムな文字列 Path=/; Expires=Fri, 26 Mar 2021 12:05:25 GMT; HttpOnly; Secure
Expire属性とMax-Age属性
Cookieの有効期限を決める属性。両方設定すると、Max-Ageのほうが優先される。
Domain属性とPath属性
Domain属性でそのCookieが利用されるホストを指定する。Path属性ではさらにそのCookieが利用されうるURLのパスを設定できる。
Secure属性
リクエストがHTTPS通信のときのみつけられる。セキュアな通信を義務付ける属性。
HttpOnly属性
Cookieの読み込みがjsなどから実行される(document.cookieなど)ことを防ぐもの。
XSS脆弱性を利用してCookieを盗み出されることを防ぐことができる。ただし、HttpOnly属性を使えばXSS攻撃そのものを防ぐことができるものではない。あくまでCookieの保護という観点のみである。
セッションを盗んで認証を突破することをセッションハイジャックという。
なぜCookieが盗まれると困るのか?→多くのWebアプリケーションでリクエストから「過去を知る」ためにCookieを使ってセッションという値をやりとりしているから。Cookieを盗まれるということは、ユーザーの過去が盗まれるということと同義である。ログイン(=認証を突破)したという「過去」が悪用されると認証情報をつかってアカウントが乗っ取られるということになる。
Cookieの上書き
Cookieの制限を悪用して、CookieのLimitをあふれさせてあらたなCookieの値で上書きする攻撃もある。
CSRF脆弱性
Cross-Site Request Forgery
Cookieの「正規のページ遷移により送られたリクエストなのかを保証できない」という点と「そのCookieがセットされた範囲へのリクエストであれば、いかなる場所からのリクエストによってもセットされる」という特徴を悪用したもの。
これを防ぐために、CSRFトークンを使う。セッションに紐づく予測しづらいデータをPOSTの前にブラウザに発行しておき、そのトークンをPOSTする際に一緒に渡すことで正規のページ遷移によるリクエストであることを保証するもの。
eTLDとTLD
TLD=トップレベルドメイン(.jp)
eTLD=Effecitveトップレベルドメインのこと。実質的にトップレベルドメインであるようなもの(.co.jp)
eTLD+1=eTLDにユーザーが付与する任意の文字列一階層分までを示す(example.co.jp)
+1の値が増えるとサブドメインの階層が増える。
https://shinkufencer.hateblo.jp/entry/2020/01/10/000000
Cookieの性質
Cookieは自動で保存される
Cookieはそれがセットされた範囲へのリクエストであれば、いかなる場所から発行されたリクエストに対しても付与され、保存される
独特なセキュリティ境界を利用して運用されている
これらは、XMLHttpRequestなどのAPIがない頃で、SOPのセキュリティの考え方が一般的になる前のルールに基づいてつくられた。1つ目と2つ目の性質が脆弱性やプライバシーにおいて問題になるケースが多い。3つ目はSOPとのセキュリティ境界の違いにより一方のセキュリティの仕組みが意味をなさなくなるもの。
5章 リソースの完全性と機密性
Webブラウザのセキュリティは受け取るリソースの完全性と機密性を前提としている。
受け取るリソースの完全性・・・信頼できるOriginが持っているデータそのものやそれが必要とするリソースは一切の改ざんなしにWebブラウザまで届けられる
受け取るリソースの機密性・・・そもそもWebブラウザに届く前に情報が盗まれていない
HSTSもでてきた!!HSTS(HTTP Strict Transport Security)
TOFUモデル(Trust On First Use)
Trust On First Use (TOFU) とは、クライアントが未知のサーバーとの信頼関係(trust relationship)を築く必要がある場合における、セキュリティ・モデルです。 https://developer.mozilla.org/ja/docs/Glossary/TOFU