MozillaのWebセキュリティガイドラインが中々良かった話

## 最初に

今まではバックエンドの開発をガシガシやっており、ここ1年ちょっとフロントエンドの開発をおこなっていてMDNに目を通す機会が増えてます。

そこでMozillaが出しているWebセキュリティガイドラインを読んでみて、中々良かったので簡単にまとめてみようと思います。

https://infosec.mozilla.org/guidelines/web_security

まずチートシートというのがあって、各ガイドラインの項目のセキュリティ上のメリットや実装の難しさのレベル、取り組むべき優先度が載っています。

基本的にアプリケーションを作成する際はこのチートシートに載っている優先度や実装の難しさを考慮してセキュリティの確保をやっていくのが良さそうだなと思いました。

https://infosec.mozilla.org/guidelines/web_security#web-security-cheat-sheet

軽く各項目を眺めていきます。

## HTTPS

最新のブラウザでシステムと通信する想定の場合はMozilla Wikiにある最新のTLS構成が良いみたいです。

https://cbjwpux4dmtcm7sfzj2i7z3dcm--wiki-mozilla-org.translate.goog/Security/Server_Side_TLS#Modern_compatibility

レガシーブラウザとの互換性を保ちたい場合は下位互換のあるTLS構成が良いみたいですが、これについてはリスクを考慮する必要がありそうです。

## HTTP Strict TransportSecurity

HTTPでのアクセスであっても、HTTPSを介してサイトに接続するようユーザーエージェントに通知するHTTTPヘッダーです。

すべてのリクエストを透過的にHTTPSにアップグレードしてくれるそうです。

ヘッダーは１つの必須パラメータ`max-age`と２つのオプションパラメータ`includeSubDomains`, `preload`で構成される。
`includeSubDomains`をつければサブドメインにも適用できるみたいです。

しかし、HTTPSがまだ有効になっていないサブドメインが無いことに注意してください。

## HTTPリダイレクト

httpからhttpsへのリダイレクトには301を使ってリダイレクトします。

別のパスにリダイレクトする場合は302を使用することができますが、サイトが別ドメインに移行した時のケースとかが該当しますかね。

## HTTP公開鍵ピンニング

「HTTP公開鍵ピンニング（HPKP）」って何？
私はこの言葉初耳でしたので調べてみました。

https://postd.cc/about-public-key-pinning/

まず、HPKPはWeb PKI問題を解決するものだそうです。
その問題とは認証局や中間認証局が、どのWebサイトでもルート証明書を発行できてしまうことらしいです。

これができてしまうと不正なドメインが標的サイトの証明書を発行することが可能になります。
これの不正な証明書発行を解決するための試みがHPKPです。
HPKPを使用する際には注意が必要みたい。

> Due to the risk of knocking yourself off the internet, HPKP must be implemented with extreme care.
>
> 出典：https://infosec.mozilla.org/guidelines/web_security#http-public-key-pinning

自身のサイトをノックアウトするということらしいのですが、つまりは以下で述べられていることだと思います。

https://postd.cc/about-public-key-pinning#gfm-3

## リソースの読み込み

javascriptやcss、画像の読み込みにはhttpsで読み込むようにしましょう

## コンテンツセキュリティポリシー

サイト運営者がサイト上リソースをどこからロードできるかを細かく制御できるようにするHTTPヘッダーです。
XSS攻撃によるリスクを軽減してくれます。
CSPはWebサイトに必須です。
CSPのメリットは、安全でないインラインJavaScriptの使用を無効にしてくれます。
インラインJavaScriptは、不適切にエスケープされたユーザー入力がブラウザによりJavaScriptとして解釈されるコードを生成する可能性があり、その可能性がXSS攻撃へと繋がります。
XSS攻撃とは？

MDNでは以下のように訳されています。

> XSS攻撃は、サーバーから受信したコンテンツに対するブラウザーの信頼を悪用します。
>
> 出典：https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

どういうことかというと、サーバーから受信したHTMLやJS、CSSなどのコンテンツをブラウザが信用していることにより、例えばそのJSのコードに外部から注入した悪意のあるJSコードであってもブラウザは信用しているので実行できてしまうということです。

CSPを有効化するには `Content-Security-Policy`というHTTPヘッダーをWebサーバーから返すように設定する必要があります。

ちなみにJavaScriptの話がメインになってしまいましたが、この機能を有効にするということはCSSのインラインコードも機能しなくなることに注意してください。
こちらに設定サンプルが書いてあります。

https://infosec.mozilla.org/guidelines/web_security#examples-4

## Contributor.json

サイトを説明するためのMozilla標準の規格のようです。
Webサイトのルートディレクトリに配置します。
内容としては、サイト内容、ソースの場所、使用する技術、サポートへの連絡方法などです。

## クッキー

Cookieは機密情報が含まれるため、なるべくアクセスが制限されるように作成する必要があります。
名前には「__Secure-」「__Host-」をつけることで安全でないソースによってい上書きされ無いようにすることができるみたい？です。（知らなかった。。）

Secureフラグを使用することでHTTPS経由のみ送信することを指示できます。

HttpOnlyフラグを使用することでJavaScriptからクッキーを送ることを制御できます。

Domainを使用すれば他のドメインからのアクセスを可能にでき、通常は可能な限り制限しておく必要がある。

## クロスオリジンリソースシェアリング

`Access-Control-Allow-Origin`を使用して、ドメイン上のコンテンツにアクセスできる外部オリジンを定義できます。

よくSPAアプリがローカルでは動いていたのにサーバーへデプロイすると動かなくなるというケースはこれが該当しますね。

Access-Control-Allow-Originを使って、許可するドメインを指定してあげれば動くようになります。

## CSRF防止

信頼できるユーザーから不正なコマンド発行されWebサイトに送信されてしまい、データに対して損害を与える攻撃です。

Webフレームワークを使っていれば、POSTリクエストを飛ばす必要があるページを生成する時にCSRFトークンを埋め込んだりしてくれるのでこれは必ず使いましょう。

## リファラーポリシー

リンクを介してサイトを移動する場合やサイトが外部リソースをロードすると`Referer`というヘッダーが使用されます。

これはどこから来たのかを特定するために便利なのですが、逆にユーザープライバシーを危険にさらす可能性があります。

サイト運営者が情報公開を制限したい場合は、HTTPリファラーポリシーを使用して、`Referer`ヘッダーを削除するか、ヘッダーに含まれる情報の量を減らしてください。

## robots.txt

サイトのルートディレクトリに配置するテキストファイルです。
これはクローラーを制御するために使用します。
検索結果などに表示したく無いサイトなどには、robors.txtの設定で拒否できます。

## サブリソースの整合性

CDNで配信されるJavaScriptライブラリのコンテンツを変更して、それらを使用する各サイトに脆弱性を仕込まれることから保護するW3Cの標準です。

この脆弱性が仕込まれると、リンクが変更されたり、サイトが改ざんされたり、機密情報を盗まれる可能性があります。

このサブリソースの整合性は、ある時点でのJavaScriptファイルの情報をバージョニングします。（実際にバージョニングしているかはわかりませんが、説明としてそのように表記しています）

こうすることで正規コンテンツのJavaScriptファイルが変更された場合に、バージョニングされたファイルと照合して変更されていたらロードを拒否します。

これはJQueryやbootstrapなどをCDNで使っているとよく見かけますね。
こんな感じのやつです。（適当ですみません。。）
https://infosec.mozilla.org/guidelines/web_security#examples-11

## X-Content-Type-Options

Internet Explorer、Chrome、Firefox 50+でサポートされているヘッダーです。
サーバーが正しいMIMEタイプを示さない限り、静的コンテンツを読み込ませ無いように指示できます。
この設定はXSS攻撃を軽減する効果もあるようです。

## Xフレーム-オプション
サイトがiframe内でどのようにフレーム化されるかをサイトが制御できるようにするHTTPヘッダーです。
クリックジャッキングに有効のようです。
クリックジャッキングとは？

https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_9.html

つまり、`X-Frame-Options`は自分のサイトに悪意のあるサイトを埋め込まれないようにframe要素を制御できるものです。

## X-XSS-保護

これはInternetExplorerとChromeの機能であるようです。
XSS攻撃を検出すると、ページの読み込みを停止します。
CSPがサポートされているブラウザであればCSPをサポートすることで本機能は不要ですが、
サポートされていない古いブラウザの場合には代わりにこれらを使ってXSS攻撃を保護するのに役立ちます。

## 最後に

知っているものもあれば知らないものもあり、非常に勉強になりました。
またいくつかのパターンでサンプルがあるので設定のヒントになります。
引き続きMDNでセキュリティ周りをページを読ませてもらい勉強していこうと思います。