コハム

Webクリエイターのコハムが提供する、Web制作に役立つ情報をまとめたブログです。

あなたのサイトは大丈夫?CSPがないと起こる恐ろしいこと

What is a Content Security Policy (CSP)?

記事は上記記事を意訳したものです。

※当ブログでの翻訳記事は元サイト様に許可を得て掲載しています。


ウェブサイトはクラウドサービスプロバイダーで設定する必要がありますが、もう一つのCSP、つまりコンテンツセキュリティポリシー(Content Security Policy)についてはどうでしょうか?

コンテンツセキュリティポリシー(CSP)は、HTTPレスポンスヘッダーで提供される標準であり、クロスサイトスクリプティング(XSS)攻撃、クリックジャッキング、パケットスニッフィング、およびウェブページのクライアントサイドでの悪意あるコンテンツの注入を防ぐのに役立ちます。Content-Security-Policyヘッダーを設定することで、指定したディレクティブに基づいてCSPを有効にし、ユーザーエージェントがサイト上のリソースをどのように読み込むかを制御できます。この記事では、コンテンツセキュリティポリシーの仕組み、CSPの設定方法、およびCSP設定に関する一般的な問題について詳しく説明します。

コンテンツセキュリティポリシーとは?

入力の検証と出力のエンコーディングがコード注入攻撃に対する最初の防御線ですが、コンテンツセキュリティポリシーは多層防御のサイバーセキュリティプラクティスにおいて重要な層を提供します。

Content-Security-Policyヘッダーは、HTTPヘッダーを通じてウェブサイトの動作に関するサーバーガバナンスのためのディレクティブを定義します。ただし、ページのCSPを設定する文字列マッチング属性を持つHTMLメタタグを提供することもできます。HTTPヘッダーは、リソース全体での表現を確実にするために推奨される方法です。一方、HTML要素は、設定された文書内に限定されます。

CSPでは、ブラウザがウェブサイトで読み込む承認された内容の出所を定義します。これには、JavaScript、CSSスタイルシート、画像などが含まれます。CSPがないと、悪意のある攻撃者が好みのコンテンツをウェブサイトに注入する可能性があります。例えば、クロスサイトスクリプティング攻撃で悪意のあるスクリプトを注入したり、クリックジャッキング攻撃でユーザーの行動を操作したりする可能性があります。XSS攻撃とUI改ざんは、承認されたコンテンツソースを定義するコンテンツセキュリティポリシーがないと悪用される可能性のある2つの攻撃脆弱性です。

ポリシーを作成する際には、コンテンツリソースの動作ポリシーを定義するためのディレクティブを指定します。コンテンツデリバリーネットワーク(CDN)を使用している場合は、コンテンツセキュリティポリシーとクロスオリジンリソース共有(CORS)の両方を設定することをお勧めします。

コンテンツセキュリティポリシーの作成方法

ウェブサイトにContent-Security-Policy HTTPヘッダーを追加することで、このポリシーを設定してウェブサイトを保護します。ポリシーを作成する際には、サイトでのコンテンツに関する権限の起点を設定する方法について追加の仕様を提供する一連のディレクティブを含めます。この起点ポリシーは、クライアントサイドのブラウザがリソースにアクセスする方法を決定します。

ウェブサイトのコンテンツセキュリティポリシーを作成するには、HTTPレスポンスヘッダーを含む設定ファイルを更新する必要があります。サーバーのセットアップやホスティングプラットフォームによって、設定ファイルへのアプローチが異なります。例えば、Apacheウェブサーバーではhtaccessまたはhttpd.confファイルを更新しますが、NGINXサーバーではサーバーブロック内での変更が必要です。

サイトに必要なCSPディレクティブを特定するには、Mozilla開発者リソースのContent-Security-Policyガイドを参照してください。セミコロンで区切られたリストでディレクティブと値のペアとして、優先するポリシーディレクティブを指定します。コンテンツセキュリティポリシーHTTPヘッダーの構文は次のとおりです:

Content-Security-Policy: <directive> <value>; <directive> <value>

ポリシーには常にdefault-srcディレクティブを含める必要があります。これは、未定義のリソースタイプに対するフォールバックを提供します。default-srcディレクティブは、多くの場合、'self'値とペアになっており、すべてのコンテンツの発信元がそのサイト自身の起点からのみであることを定義します。その場合、ポリシーは次のようになります:

Content-Security-Policy: default-src 'self'

default-src 'none'を設定する場合、noneキーワードではリソースが読み込まれないため、特定のタスクに対して一部のリソースを許可するための追加のディレクティブを提供する必要があります。default-srcディレクティブ以外に、組織のニーズに合わせてどのディレクティブを使用するかを決定できます。

許可されるソースを含むヘッダーを準備する際は、許可リストで指定されるソースについて意図的に考えてください。詳細な権限を設定することで攻撃対象領域を減らすことができますが、Amazon S3バケットを指すワイルドカードドメインなどの広範な権限を設定すると、脆弱な攻撃対象領域が広がる可能性があります。攻撃者がサイトの脆弱性を知り、許可されるソースを特定できる場合、同じ許可されたソース(AWS S3バケットなど)から独自のワイルドカードサブドメインを立ち上げ、悪意のあるコードをワイルドカードエンティティに読み込んで注入する可能性があります。許可されるソースに対する厳格な権限設定は、このようなバイパス攻撃を防ぐのに役立ちます。

次のセクションの例を参照して、CSPを定義する際によく使用されるディレクティブを確認してください。

サンプルCSPヘッダー

このセクションでは、よく使用されるディレクティブの簡単な例を紹介します。CSPにはこれらのディレクティブやその他のディレクティブが含まれる場合があり、これらの例は教育的なリソースとして提供されています。ウェブサイトのセキュリティ要件を満たす完全なコンテンツセキュリティポリシーを定義していることを確認してください。

信頼できるドメインとそのサブドメインからのコンテンツを許可するには、self値に信頼できるドメインとサブドメインを識別するワイルドカードを追加します(your_domainを自分のドメインに置き換えてください):

Content-Security-Policy: default-src 'self' your_domain *.your_domain

すべてのコンテンツがトランスポート層セキュリティ(TLS)を使用して読み込まれるようにするには、ドメインの前にhttps://を付けます(example.comを自分のドメインに置き換えてください):

Content-Security-Policy: default-src https://example.com

script-srcディレクティブは、インラインスクリプト、イベントハンドラー、およびscriptタグに保持される情報を含む、JavaScriptの許可されるソースを識別します。script-srcディレクティブにソースを指定しない場合、default-srcディレクティブで許可されたソースにフォールバックします。このディレクティブでは、ポリシーが通常許可しない場合でもインラインスクリプトを許可する暗号化トークンを動的に生成するnonce-sourceまたはhash-sourceを指定できます。次のCSPヘッダーは、自身の起点とドメインからのスクリプトを許可します:

Content-Security-Policy: script-src 'self' https://your_domain

一方、ファイルハッシュを生成する場合は、ディレクティブとscriptタグの整合性属性の両方にそれを含めます。ポリシーは、一意の英数字ハッシュ文字列を使用して次のようになります:

Content-Security-Policy: script-src 'sha384-your_alphanumeric_hash_string'

ウェブアプリケーションのニーズに応じて、img-srcやstyle-srcディレクティブなど、他のディレクティブを使用して異なるタイプのコンテンツの許可されるソースを指定できます。サイトが多様なコンテンツを提供し、コンテンツ注入攻撃から保護したい場合、異なるコンテンツソース間の区別を考慮するため、Content-Security-Policyヘッダーが長くなる可能性があります。

ポリシーを設定する際、レポーティングモードでデプロイメントをテストしたい場合があります。ヘッダーに-Report-Onlyを追加すると、ポリシー自体を強制せずに、指定されたリソース識別子(URI)にポリシー違反を報告します。Content-Security-Policy HTTPヘッダーの代わりに、Content-Security-Policy-Report-Onlyヘッダーを使用します。

アクティブなポリシーでレポーティングを有効にするには、CSP違反レポートを収集するURIを指定したreport-toディレクティブを指定します。次のヘッダーのようになります(your_domainを自分のドメインに置き換えてください):

Content-Security-Policy: default-src 'self' your_domain; report-to http://reports.your_domain/collector.cgi

その後、CSPレポートを確認して、コンテンツポリシーの機能を分析し、設定から生じる問題を特定できます。report-toディレクティブは、非推奨のreport-uriディレクティブに代わるものですが、report-toをまだサポートしていないブラウザとの互換性のために両方のディレクティブを含めることができます。

その他によく使用されるディレクティブには、base要素を管理するbase-uri、ネストされたブラウジングコンテキストのchild-src、特定のAPIとWebSocketsを制限するconnect-src、許可されるフォントのfont-src、フォーム送信のform-action、frameとiframe要素のframe-src、audioとvideo要素のmedia-src、およびobjectとembed要素などのプラグインのobject-srcがあります。

まとめ

コンテンツセキュリティポリシー(CSP)は、ウェブサイトのセキュリティを強化する重要なツールです。CSPを適切に実装することで、クロスサイトスクリプティング(XSS)攻撃、クリックジャッキング、その他の悪意あるコンテンツ注入から、ウェブサイトを保護することができます。

CSPの設定には以下の重要なポイントがあります:

  1. HTTPレスポンスヘッダーを使用してCSPを設定する。
  2. 必要なディレクティブを慎重に選択し、適切な値を設定する。
  3. default-srcディレクティブを必ず含め、他のディレクティブのフォールバックとして使用する。
  4. 安全でないディレクティブ(unsafe-inlineやunsafe-eval)の使用を避ける。
  5. 許可するソースを具体的に指定し、可能な限りワイルドカードの使用を避ける。
  6. レポーティングモードを使用して、ポリシーの効果を確認し、必要に応じて調整する。
  7. 定期的にCSP設定を見直し、新しい脅威や変更に対応する。

CSPの実装は、ウェブサイトのセキュリティ戦略の重要な部分ですが、それだけでは完全な保護を提供できません。入力検証、出力エンコーディング、その他のセキュリティベストプラクティスと組み合わせて使用することで、より強固な防御を構築できます。

最後に、CSPの設定と管理には継続的な注意が必要です。新しい脅威が出現し、ウェブサイトが進化するにつれて、CSPも適応し、更新される必要があります。定期的な監査はCSPが効果的であり続け、ウェブサイトのセキュリティを最適な状態に保つための重要な実践です。

©コハム