【視聴メモ】Securing Web Apps with Modern Platform Features (Google I/O ’19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=DDtM9caQ97I

Speaker(s): Artur Janc, Lukas Weichselbaum

## Abstract

> Common vulnerabilities such as XSS, CSRF, and others have long plagued the web, accounting for most of the high-risk flaws reported under Google's Vulnerability Reward Program. Learn about the latest web platform security mechanisms to protect your apps from injections and isolate them from dangerous sites. You'll leave with a security checklist for defending your applications with new browser features based on Google Security Team's experience in protecting the web's most sensitive apps.

訳

> XSSやCSRFなどのありがちな脆弱性は長きに渡ってWebを悩ませ、またGoogleのVulnerability Reward Programでも頻繁に報告されています。最新のWebプラットフォームにおけるセキュリティの仕組みを学んで、あなたのサービスをインジェクションからまもり危険なサイトから隔離しましょう。また、Webでもっともセンシティブなアプリを守っているGoogleのセキュリティチームの経験によって得られたブラウザの新機能によって、あなたのアプリケーションを守るためのチェックリストを知りましょう。

## Contents

### Common web secrurity flows

* Google Vulnerability Reward Program
 * 発見された脆弱性の半分はWebに関するもの
 * というかXSSとCSRFがほとんど

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/bc2d2126-b2ba-2fa9-943c-3de6bc4e3f72.png)

### Web platform security features

#### injection対策

* つまりXSS対策
* CSP: Content Security Policy
    * XSSへの対策として、どのスクリプトが実行可能か、どのプラグインがロード可能かを指定する
    * HTTPリクエストのレスポンスヘッダーで`Content-Scurity-Policy`を設定する
    * `Content-Security-Policy-Report-Only`でレポートするだけで実行できるようにすることもできる
    * 今どきのサイトだとCSPの設定はとても難しく下図のようになってしまう
        * 読めないしメンテナンスできないしバイパスされてしまう（？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/65755752-9d62-ca2c-9ebf-d4d7726a95d8.png)

* nonce-based CSP
    * CSPヘッダーに`script-src 'nonce-...' 'strict-dynamic'`を指定する
    * nonceのついたscriptタグしか実行されなくなる
    * nonceをリクエストごとに変更すれば攻撃者は予測できない
    * だが動的にサードパーティーのスクリプトを読み込みたいときはどうする？
* CSP3では`strict-dynamic`キーワードが実装された
* nonceのついたスクリプトから生成されたスクリプトは実行可能になる
* 具体的にどうやってCSPを導入するか
    * STEP 1: onclickやhrefで指定されるインラインイベントハンドラーをなくす
    * STEP 2: サーバーサイドテンプレートにてnonceを指定する
    * STEP 3: レスポンスヘッダーでCSPを指定する
        * Googleでは`unsafe-eval`を指定していることも多いがなくしたほうが良い
        * `strict-dynamic`も必要がなければなくす
* 詳細は csp.withgoogle.com
* Over 60 dangerous DOM APIs ↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/a3322706-8e3d-70c7-095d-d24af13ac318.png)

* Trusted Types
    * innerHTMLなどが `Trusted*` というオブジェクトしか受け付けなくなる
    * こちらもCSPで指定し、内容は `trusted-types` 
        * レポートモードもある
    * `element.innerHTML = location.hash.slice(1);` が動かなくなる
    * TrustedTypes.createPolicyでポリシーオブジェクトを作成し、それが持つ`createHTML`などのメソッドでTrustedオブジェクトを生成する
    * `default` ポリシーは`string`が割り当てられたときのfallbackとして機能する
    * サニタイズの処理をポリシーオブジェクトに集約できるのが嬉しい
* 詳しくは bit.ly/trusted-types

#### isolation対策

* つまりCSRF対策
* まずは言葉の定義について
    * same-origin: 同じスキーマ、ホスト、ポートを持ったサイト同士のこと (https://www.google.com/foo, https://www.google.com/bar)
    * same-site: 同じスキーマとドメインを持ったサイト同士のこと (https://mail.google.com/, https://photos.google.com/)
    * cross-site: その他 (https://www.youtube.com/, https://www.google.com/)
* `Sec-Fetch-Site` と ｀Sec-Fetch-Mode` ヘッダー
    * fetchリクエストを送ったりするときにブラウザがつける
    * same-originかどうかやcorsモードかどうかがわかる
* ヘッダーがどういうときにリクエストを受け付ければいいか（下図）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/38a0ae1d-6e28-97c1-86e4-afe9c29cc130.png)

* SameSite cookies
    * `Set-Cookie` ヘッダー
    * 他のサイトにcookieを送る必要がなければ指定する
* Cross-Origin Opener Policy
    * same-originでもsame-siteでもないサイトによって`window.open`されたページは参照を取れなくなる

発表全体のまとめ（下図）
わかりやすい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/09c7c8cb-3493-adce-401a-0204a9df05a3.png)


## Memo

* Webセキュリティの基本的な話（XSSとはなにかみたいな）から始まるので退屈な気がするけど、後半はそれらに対する最新の対策方法についてわかりやすくまとめられていてためになった