ここ数週間、このブログではセキュリティ関連のHTTPヘッダを数多く取り上げてきたが、その中で最も重要なのはContent-Security-Policy(CSP)である。このヘッダが提供する保護レベルの高さもさることながら、残念ながら、このヘッダを最初に正しく実装するのが難しいという理由もある。最近説明したflightPATHのトラフィック管理ルールと同様に、edgeNEXUSのウェブサイトとその訪問者を保護するために私たち自身が使用しています。
私たちは大変な仕事をこなし、痛みを感じてきたので、あなたがそうする必要はない。しかし、実施する前にある程度の熟考と計画が必要なことは否定できない。しかし、それだけの価値はある。このヘッダーのコンセプトはとてもシンプルで、同様に強力だ。一言で言えば、このヘッダーを使用して、ウェブサイトに読み込まれるコンテンツの許可されたオリジンを指定します。これにより、クロスサイトスクリプティング(XSS)やクリックジャッキングなど、ますますダイナミックになったインターネット上で流行しているコードインジェクション攻撃の数々を強力に防御することができます。
JavaScript、CSS(CSSは危険です)、HTMLフレーム、フォント、画像、Javaアプレットのような埋め込み可能なオブジェクトなどです。多くの選択肢があるのは素晴らしいことだが、ここで困難が生じる。今日のウェブサイト(私たちのウェブサイトを含む)には、多くのソースから多数のこれらのコンテンツタイプが含まれており、ポリシーの中でこれらすべてを特定し、説明することは、かなりの努力が必要です。
その前に、ヘッダーの値の要素とポリシーがどのようなものかを見てみましょう。おわかりのように、ポリシーは基本的にコンテンツタイプ (この例ではすべて -src で終わっています) と、それぞれのタイプに対して許可されるソースの長いリストです。これらをまとめてポリシーディレクティブと呼びます。
default-src「self」data:; script-src「self」「unsafe-inline」; connect-src「self」; img-src「self」data:; style-src「self」「unsafe-inline」data:; font-src「self」data:; child-src「self」
検討できるコンテンツタイプは他にもありますが、上記に示したものが(リスクと普及率に基づく私たちの見解では)最も重要な指令です。以下に、それぞれがどのようなコンテンツに関連するのか、詳しく説明する;
- default-src– 後から指定しない場合、ほとんどのコンテンツタイプ(すべてではない)のデフォルト値。
- script-src– スクリプト(JavaScriptを含む)の許可されたソース。
- connect-src – 接続に許可されるソース (例えば、チャットアプリケーションで使用される WebSocket や EventSource など)
- img-src– 画像のソースを許可する。
- style-src– CSS の許可されたソース。
- font-src– フォントの許可されたソース
- child-src– フレームおよび iframe に許可されるソースです。
これらのコンテントタイプとその値は、セミコロンで互いに区切られる(delimited)。各タイプは、以下の値の1つ以上を持つことができます;
- none’– このコンテンツタイプを許可しない。
- 「self」– このサイトから直接発信されたコンテンツであれば、このコンテンツタイプを許可します(サブドメインは許可しません)。
- unsafe-inline’– インラインCSSとJavaScriptを許可する(これは残念ながら非常に一般的です。)
- データを使用します: – インラインデータソースを許可する(通常、パフォーマンスを向上させるためにフォントや画像をインラインで提供するために使用される)
- https:– HTTPS経由でのみこのコンテンツタイプを許可します。
- unsafe-eval’– コード実行につながる可能性のある危険なメソッドを使ったテキストの解析を許可する。
- domain-name– 指定されたdomain-name(言い換えれば、リモートドメイン)から発信された場合、このコンテンツタイプを許可する。
- * 任意の ドメイン
各値の区切りには、単純なスペースが使われる。値がドメイン名でない限り、シングルクオート「’」は必須である。ブラウザの拡張機能やプラグインは、ユーザー(結局のところ、それらをインストールした人)から信頼されているため、安全であるとみなされるため、除外されることに注意してください。
かなり専門的で複雑に見えるが、一歩ずつ取り組んでいけば、すぐに方針が見えてくる。早速、2つの例を見てみよう。まず最初に、HTTPで提供されるシンプルな内部ウェブサイトを試してみよう。必要なものは以下の通りだ;
- default-src「self」データ:– インライン・オブジェクトを含め、自サイトのコンテンツのみを許可する
- script-src「self」「unsafe-inline」– インラインを含め、自サイトのスクリプトを許可する。
- connect-src「self」– 自サイトからの接続を許可する。
- img-src「self」データ: – インラインのものも含め、自サイトの画像を許可する
- style-src「self」「unsafe-inline」data: – インラインスタイルを含む、自分自身のサイトからのCSSを許可する
- font-src「self」データ:– インラインフォントも含め、自サイトのフォントを許可する
完全なヘッダー値はそれなりに短い:
default-src「self」data:; script-src「self」「unsafe-inline」; connect-src「self」; img-src「self」data:; style-src「self」「unsafe-inline」data:; font-src「self」data:
2つ目は、Google Analytics(GA)、インラインCSS、フォント、画像、あなたのサイトのCSS、他のさまざまなウェブサイトの画像を使用するSSL/TLSで保護されたインターネットに面したウェブサイトです。必要なものをひとつひとつ見ていきましょう(あまり違いはありません);
- default-src「self」data: https:– HTTPS経由でのみ、インラインオブジェクトを含む自サイトのコンテンツのみを許可する。
- script-src「self」「unsafe-inline」https:– 自サイトのスクリプト(インラインのものも含む)を HTTPS でのみ許可する。
- img-src「self」「unsafe-inline」¦ https: – HTTPS経由でのみ、インラインのものも含め、どのサイトからの画像も許可する。
- style-src「self」「unsafe-inline」https:– インラインも含め、自サイトからのCSSのみをHTTPSでのみ許可する。
- font-src「self」「unsafe-inline」https:– 自サイトのフォントのみを、インラインも含めて、HTTPS でのみ許可する。
それをすべて足すと、この少し長い方針になる:
default-src「self」data: https:; script-src「self」「unsafe-inline」*.google-analytics.com https:; img-src「self」「unsafe-inline」* https:; style-src「self」「unsafe-inline」https:; font-src「self」「unsafe-inline」https:
かなり簡単だと思う。Googleは以前はあまりCSPに「フレンドリー」ではなかったが(このヘッダー値は少なくとも2倍はあった)、ありがたいことに最近大きく進歩した。Googleのコードはインライン・スクリプトとして実行されるため、script-srcに*.google-analytics.comドメインをコンテンツ・タイプ値として追加する必要がないことにお気づきでしょう。
読み込まれるリソースは間違いなくページごとに異なるため、ウェブサイトのページごとにポリシーを作成するのが理想的ですが、これはかなり負担が大きく、可能性のあるすべてのソースをカバーするポリシーを作成する方がはるかにシンプルで、なおかつ効果的です。私たちのGitHubページにある例のほとんどはこの方法をとっていますが、特定のページにより大きな保護を提供したい場合は、この方法もあります。
テストとトラブルシューティングには、Google Chromeのデベロッパーツールを使うことを強くお勧めする。問題のサイトにアクセスし、F12キーを押し、[ネットワーク]をクリックし、[キャッシュを無効にする]がチェックされていることを確認し、ページをリロードします。エラーがあれば、はっきりとハイライトされます。このブログの一番下に、あなたのポリシーがunsafe-inlineをブロックしていて、Google Analyticsを使用している場合に表示される可能性のあるエラーメッセージの画面があります。
必要に応じてポリシーを調整し、繰り返してください。理想的には、テストするflightPATHルールを適用したテスト専用の仮想サービスを使用してこれを行いますが、テスト中に実際の顧客やクライアントに影響を与えないように、別の仮想IPを介して同じサイトを提供します。
いつものことですが、ロードバランサーを使うことの大きな利点は、すべてのサーバー(とサイト)を守るために、中央の一箇所でこれを行うだけでよいということです。開発者やウェブサーバーの再設定に頼る必要はありません。edgeNEXUSロードバランサーでは、jetPACK自動設定テンプレートをインポートし、保護したい仮想サービスにflightPATHトラフィックルールを割り当てるだけです(適切な修正後)。
このルールはヘッダーが存在しない場合にのみ追加するので、ウェブサーバーがすでにヘッダーを挿入している場合や、特定のページにのみ挿入している場合でも機能します。このルールは標準の仮想サービス設定の一部であるべきで、どんなサイトでも失うものは何もありません。このjetPACKや他の多くのjetPACKはedgeNEXUS Githubサイトからダウンロードできます。
flightPATHはedgeNEXUSが開発した動的なイベントベースのルールエンジンで、負荷分散されたIP、HTTP、HTTPSトラフィックをインテリジェントに操作し、ルーティングします。高度に設定可能で強力でありながら、非常に使いやすい。
これらの関連リンクは、もっと知りたいなら一読の価値がある;
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
https://developer.mozilla.org/en/docs/Web/Security/CSP/CSP_policy_directives
http://content-security-policy.com/
https://www.clickintelligence.co.uk/header-response-checker/
ここ数週間、このブログではセキュリティ関連のHTTPヘッダを数多く取り上げてきたが、その中で最も重要なのはContent-Security-Policy(CSP)だろう。