API設計時によくわからず悩まされたセキュリティ系のHTTPレスポンスヘッダー

#目次
1. はじめに
2. Strict-Transport-Security（HSTS）
3. Access-Control-Allow-Origin

## 1. はじめに
以前、APIを作成し公開しようとしたのですが、HTTPヘッダーを付与してあげるだけでセキュリティーが向上するよとアドバイスをいただいたので、その備忘録も兼ねてこちらに投稿したいと思います。

もちろん、他にもつけておいた方がいいHTTPヘッダーもあると思います。
ここではあくまで私が勉強して理解できた範囲で、説明しますのでよろしくお願いします。
IT初心者なのでアドバイスなどもいただけると嬉しいです。

そもそもここで扱うHTTPレスポンスヘッダーはクライアント側が使用しているWebブラウザやPostmanなどのAPI呼び出しのツールに依存する（レスポンスヘッダーを受け取るWebブラウザ等がレスポンスヘッダーをみてwebブラウザが対応する）ので、古いバージョンのWebブラウザであったり、もし自作のWebブラウザみたいなものが作れたら通用しない場合があるので注意が必要です。


## 2. Strict-Transport-Security
[MDS Strict-Transport-Security](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Strict-Transport-Security)によると、
>HTTP の Strict-Transport-Security レスポンスヘッダー (しばしば HSTS と略されます) は、ウェブサイトがブラウザーに HTTP の代わりに HTTPS を用いて通信を行うよう指示するためのものです。

とあるように、HTTPS通信を強制させるようなヘッダーです。

値は「max-age=有効期間(秒)」が必須、「includeSubDomains」(適用範囲をサブドメインも含める場合はこの値も入れる)がオプションです。

| 値|必須/選択|説明|
|:---|:--|:-:|
| max-age=有効期間(秒)  |  必須  | ブラウザがHTTPS通信を強制させる期間(秒単位)  |
| includeSubDomains   |  選択  |  全てのサブドメインにもHTTPS通信の有効期間が適用される(※1) |
| prelocad           |  選択        |       preload listに登録している場合に使用(説明は後述)       |

※1 includeSubDomain付きのHSTSヘッダーをブラウザが受け取ったあと、新たに別サイトを作成するためにサブドメインを切った場合その別サイトにもHTTPS通信の強制がかかります。また別のWebサーバーを経由した場合も同様に強制がかかります。

**HSTSを使用しない場合の想定される脅威**
HTTPSが利用可能なWebサイトであっても、攻撃者が標的ユーザをHTTPで接続するよう誘導することで、通信内容を盗聴可能となります。

**max-age=の値について**
max-age=有効期間の有効期間は、31536000秒(1年)や15552000秒(半年)、2592000秒(1ヶ月)がよくみられます。私は以前1000秒にしていたところ、短すぎると言われました笑

参考例）Strict-Transport-Security: max-age=31536000; includeSubDomains

**単にHSTSを使用しても防ぎきれない脅威**
HSTSはレスポンスヘッダーをブラウザ等が受け取った時からブラウザ側がHTTS通信を強制します。逆にいうと、最初のアクセスはHTTPでも通ってしまいます。

**上記の脅威に対する対応方法**
そのためにChromeやFirefoxなどの各ブラウザでは、HSTS preload list（ 参考：[firefoxのHSTS preload list](https://hg.mozilla.org/mozilla-central/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc)）というのがありそのリストに登録されているドメインは最初のアクセスをHTTPS通信するようにWebブラウザ側で設定されています。

登録は以下のURLにしたがって行います。HTTPS通信を徹底する場合はこの設定をする必要があります。
[HSTS preload list Subumission](https://hstspreload.org/)
<details><summary>登録に必要な条件(上記サイトに記載されている内容の日本語訳です)</summary>1. 有効なSSL証明書を使っていること
2. 80番ポートを使用していたら、同一ホストのHTTPからHTTPSにリダイレクトさせること
3. 全てのサブドメインでもHTTPS通信を使うこと（サブドメインをDNSで管理している場合は、wwwサブドメインをHTTPS通信できるようにすること）
4. ベースドメインへのアクセス(HTTPSのリクエスト)でHSTSヘッダーを使用すること  
　　　　1. max-ageの値は最低31536000秒(1年)でなくてはならない
　　　　2. includeSubDomainを指定しなければならない
　　　　3. preloadを指定しなければならない()
　　　　4. 
</details>

**対応しているWebブラウザ**
以下のサイトに一覧が載っていました。
https://caniuse.com/#feat=stricttransportsecurity



## 3. Access-Control-Allow-Origin
クロスドメインアクセスを許容する範囲を指定できます。
本来、XMLHttpRequestによる通信では他ドメインからのレスポンスを読み込まないようにする同一生成元ポリシー(SOP)と呼ばれるポリシーがあります。そのため、ドメインの異なるサイトからデータを取ってこようとすると、以下のようなエラーが出てしまいます。
>"XMLHttpRequest cannot load https://xxxx.xxx. Origin https://xxxx.xx is not allowed by Access-Control-Allow-Origin." (Chromeの場合)

それを回避するために登場したのがCORS(オリジン間リソース共有（[MDS CORS](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)）です。
Access-Control-Allow-Originをレスポンスヘッダーにつけることで、クライアント側のクロスドメインアクセスを制御します。クロスドメインアクセスが行われた場合、中継するドメインがOriginヘッダーを付与して、そのOriginヘッダーの値をサーバー側が判断して
よくデフォルトで『Access-Control-Allow-Origin: *』というのが設定されていて、全てのクロスドメインアクセスを許容してしまいます。この設定をしている場合の脅威については以下に記載しています。


**想定される脅威**
クロスドメインアクセスを広範囲または無制限に受容している場合、悪意のある第三者がこれを悪用することで、被害者になりすまして機微な情報を取得したり、クロスサイトリクエストフォージェリ(CSRF)といった攻撃を行うといったことを許してしまう可能性があります

**対応策**
クロスドメインを共有


※随時更新予定
4. X-Content-Type-Options
5. Cache-Control