CloudFrontにはHTTPレスポンスヘッダーを指定する機能があり、セキュリティに関するHTTPヘッダーを比較的容易に設定できます。
今回は、CloudFrontの設定項目からセキュリティヘッダーを見ていきたいと思います。
CloudFrontを利用しない場合もこれらのHTTPヘッダーの設定は推奨されるものです。
CloudFrontでのレスポンスヘッダー
レスポンスヘッダーポリシーとは
CloudFrontには、レスポンスヘッダーポリシーがあります。これを対象ビヘイビアーに設定することでHTTPレスポンスヘッダーを指定できます。
今回のテーマとしているセキュリティヘッダーの他、CORSや任意のカスタムヘッダーも設定可能です。
また、オリジンから返されたレスポンスヘッダーから特定のヘッダーを削除することもできます。
レスポンスヘッダーポリシーは、ビヘイビアーを設定する前にあらかじめ作成しておきます。

最初からSecurityHeadersPolicy等のポリシーが用意されていますが、それぞれの事情に合わせたカスタマイズしたポリシーが必要です。
とくに、この後に説明するCSP等はWebサイトごとに適切な設定が異なります。適切なポリシーを作成しましょう。
レスポンスヘッダーポリシーのセキュリティヘッダーに関する説明は、以下にAWSのドキュメントがあります。
オリジンのオーバーライド
セキュリティヘッダーのそれぞれの項目にオリジンのオーバーライドというチェックボックスがあります。
これをチェックすることにより、オリジンからのレスポンスに含まれるヘッダーを上書きできます。
常に固定値を返したいときはこれを有効にしてCloudFrontでヘッダーを設定してください。 逆に、細かく出し分けするときはチェックを外し、オリジン側で付与したヘッダーを返すようにできます。
チェックを外している場合も、オリジンからのレスポンスにそのヘッダーがない場合はCloudFrontがそのヘッダーを設定します。
セキュリティヘッダー
設定可能セキュリティヘッダー一覧
セキュリティヘッダーには以下のようなものがあります。
X-XSS-Protection以外のすべてのヘッダーについて設定を検討してください。
| ヘッダー | 概要 |
|---|---|
| Strict-Transport-Security | HSTSと言われ、このドメインに対してHTTPSで接続するように指示します。ユーザがhttp://...というURLを入力しても、ブラウザはhttps://...にアクセスするようになります。 |
| X-Content-Type-Options | ファイル内容の判定にContent-Typeヘッダーを利用し、ファイル名や内容から独自に判断しないよう指示します。ファイルに対して意図しない解釈をされてJavaScript等が不正に実行されることを防ぐことができます。 |
| X-Frame-Options | そのページを<frame>、<iframe>、<embed>、<object>の中で表示できるか指示します。クリックジャッキング対策になります。 |
| X-XSS-Protection | 非標準で、設定によっては違う脆弱性や不具合が発生する可能性があります。 ブラウザに搭載されたXSSフィルタリングを有効にします。ブラウザによって実装も違いますし、本番サイトでは利用しない方がいいかと思います。 |
| Referrer-Policy | ページ遷移のときにRefererヘッダーを送るかどうかを指示します。外部サイトへ遷移したときに、こちらのサイトのURLが分からないようにできます。 |
| Content-Security-Policy | CSPと呼ばれ、XSS攻撃を防止するための重要なヘッダーです。細かい制御が可能で、クリックジャッキング対策も可能です。 |
ここから、各ヘッダーについて詳しく説明していきます。
Strict-Transport-Security
例: Strict-Transport-Security: max-age=31536000

HSTSと言われ、このドメインに対してHTTPSで接続するように指示します。
現在は機密情報や個人情報を扱わないサイトであっても、平文のHTTPではなく暗号化したHTTPSで通信する事が推奨されています。
HSTSでは、ユーザがhttp://で始まるURLを入力したとしてもブラウザはhttps://へアクセスするようになります。
max-ageにより、HSTSをブラウザが記録する期間(秒数)を指定する必要があります。
また、他にもサブドメインもすべてHTTPSのみで接続させるオプションがあります。
X-Content-Type-Options
例: X-Content-Type-Options: nosniff

このヘッダーの値はnosniffだけです。Content-Typeヘッダーが適切に設定されていることを示します。
かつてIE(Internet Explorer)では、Content-Typeヘッダーを無視してコンテンツ内容からMIMEタイプ(コンテンツの種類)を判定していることがありました。
この動作を抑止するためのヘッダーとして登場したのがこのX-Content-Type-Optionsです。
現在のブラウザでも、このオプションは有効です。
scriptやstyleとして読み込むURLでContent-TypeがJavaScriptやCSSのMIMEタイプになっていない場合は、そのファイルの読み込みをブロックします。
セキュリティのために、このヘッダーを設定した上で適切なConent-Typeヘッダーを設定してください。
X-Frame-Options
例: X-Frame-Options: SAMEORIGIN

そのページをフレームやインラインフレームで表示できるかを示します。
値はフレーム内での表示を完全に拒否するDENYと、同じオリジンの場合のみ許可するSAMEORIGINがあります。
このヘッダーにより、クリックジャッキングを防ぐことができます。
クリックジャッキングは、攻撃対象のページをインラインフレームに読み込み、透過したうえで攻撃ページに重ね合わせる攻撃手法です。
ユーザは攻撃ページを操作しているつもりで、実際は攻撃対象ページの操作をさせられることになります。
(詳細はIPAのページ等を参照してください)
CSP(Content-Security-Policyヘッダー)のframe-ancestorsディレクティブでより細かい指定も可能ですが、こちらのヘッダーの方が古いブラウザから対応しています。
クリックジャッキングやフレームを用いた不正利用を防ぐため、適切なX-Frame-Optionsヘッダーを設定してください。
X-XSS-Protection
例: X-XSS-Protection: 1; mode=block

ブラウザのXSSフィルタリング機能を有効にしますが、最新のブラウザではこの機能は削除されています。
mode=blockが無く1のみを指定した場合、一部のJavaScriptコードのみ実行されて不具合や脆弱性が発生する可能性があります。
このヘッダー設定を行う場合、1; mode=block(XSS検出時はページ表示自体を防止)か0(XSSフィルタリング機能の無効化)以外の設定は行わない方がいいかと思います。
このヘッダーは非標準で標準化予定もないため、公開サイトでは利用しないように呼びかけられています。
標準化されていないためブラウザによって違う動きをする可能性がありますし、最新ブラウザではこの機能は削除されています。
さらに、前述したように、設定値によってはこの機能自体が脆弱性になってしまう可能性があります。
HTTPヘッダーによるXSS(クロスサイトスクリプティング)対策はCSPを活用して行った方が良いかと思います。
それでもこのヘッダーを設定したい場合は、以下のサイト等を参考に慎重に検討してください。
Referrer-Policy
例: Referrer-Policy: strict-origin-when-cross-origin

画面遷移や画面内のリソースを読み込むリクエストのとき、ブラウザはリンク元URLを記したRefererリクエストヘッダーを送信することがあります。
このReferrer-Policyヘッダーは、このRefererヘッダーにどこまで含めるかを指定しします。
(こちらはReferrerなのに対し、リクエストヘッダーはRefererと綴りが違うので気を付けてください)
Refererヘッダーにはリンク元URLが含まれますが、これを送信されたくない場合があります。
社内向けのサイトや管理サイト等では存在自体があまり外部へ知られない方がいいでしょうし、SNSやWebメール等では実在するユーザIDやメッセージIDを含むURL等が外部へ知られない方が安全です。
Referrer-Policyヘッダーは、どのような時にどのようなRefererヘッダーを付けるか指定します。
no-referrerとすれば完全にRefererヘッダーを送信しないようにできますし、same-originとすれば同一オリジンのときのみ送信します。
最近のブラウザではstrict-origin-when-cross-originがデフォルトのようです。
これは、同一オリジンのときのみパスやクエリー文字列を送信し、違うサイトへの遷移ではパスやクエリー文字列を含まないオリジン情報のみ送信するものです。
(ただし、HTTPからHTTPSへ遷移するときはRefererヘッダー自体を送信しないように要求します)
他にも設定可能なディレクティブが存在します。以下のサイトで、分かりやすい例を含めて説明されています。
これはHTML内の<meta>要素でも設定可能です。
Content-Security-Policy
例: Content-Security-Policy: default-src 'self'; img-src 'self' https://*.google-analytics.com https://*.googletagmanager.com; connect-src 'self' *.google.com https://*.google-analytics.com https://*.googletagmanager.com

CSP(Content Security Policy)は、読み込み可能なリソースやフォーム送信先を指定して制限できます。
CSPは<policy-directive>; <policy-directive>のような形で複数の設定をセミコロン(;)区切りで記載します。
ここで<policy-directive>は、ディレクティブ(default-srcやimg-src等の設定項目)とその設定値をスペースで区切った形(<directive> <value1> <value2>)です。
(<directive1> <value1-1>; <directive2> <value2-1> <value2-2>のような形でディレクティブの設定を続けて書いていきます)
設定できるディレクティブが豊富にあり、ブラウザのバージョンによってもその対応状況は違います。
以下のサイトで、各ディレクティブも含めて説明されています。
default-srcはフェッチディレクティブ(リソースのロード元を制限するディレクティブ)のデフォルト値を指定します。
上に書いた例ではdefault-srcとimg-srcとconnect-srcのみを定義しています。
ブラウザが画像をロードするときはimg-srcにより許可された場所からのみロードを行います。
スタイルシートを読み込もうとしたときはstyle-srcに従いますが、ここには定義がないためdefault-srcに従います。
この場合は'self'のみが許可され、URLのスキーム、ホスト、ポート番号が同じ場所からしかロードできません。
CSPでは、HTML内に直接記載されたスクリプトやスタイルシート(インラインスクリプト、インラインスタイル)も禁止されており、使用するためには明示的に許可する必要があります。
インラインスクリプトも含めてスクリプト実行が制限されることで、ユーザが入力したスクリプトがHTMLに埋め込まれてもブラウザ上で実行されなくなります。
これは、XSS(クロスサイトスクリプティング)のリスクを軽減するためのCSPの重要な機能です。
インラインスクリプトを許可する方法に、script-srcディレクティブに設定できる'unsafe-inline'があります。
これはHTML内のスクリプトを無条件に動かすことを許可するもので、前述のXSS等のリスク軽減ができなくなるので注意してください。
'unsafe-inline'を使わずに設定できないか慎重に検討する必要があります。
'unsafe-inline'ですべてのインラインスクリプトを許可する代わりに、nonceやハッシュで特定のスクリプトを許可することもできます。('nonce-<base64-value>'や'<hash-algorithm>-<base64-value>')
この場合は設定値が個別に変わるため、CloudFrontでの設定は難しくなります。オリジンサーバで動的にCSPヘッダーを生成する必要があるかもしれません。
また、イベントハンドラーのみ許可したいときは'unsafe-hashes'というソースも用意されています。詳細は先のドキュメントを参照してください。
CSPでは、読み込み可能なリソースやフォーム送信先を制限することでXSS攻撃やコンテンツ改ざん等の影響を軽減できます。
そのためには、許可するリソースを最小限にし、'unsafe-inline'のようなリスクの増える許可を出さなくていいようWebサイトを開発した方が効果があります。
早い段階からCSPについて検討し、Webサイトの開発に盛り込んでいく必要があると思います。
CSPはディレクティブも多く設定が大変なヘッダーですが、セキュリティのために適切な設定を検討してください。
最後に
今回は、CloudFrontのレスポンスヘッダーポリシーで設定可能なセキュリティヘッダーを紹介しました。
1つを除いては設定することが推奨されるヘッダーですので、セキュリティを高めるために設定の検討をしてください。
また、セキュリティに関する推奨設定はどんどん変わっていくものですので最新情報の確認をしてください。