Defaults.Exposed › 修正 › Content-Security-Policy(CSP)
Content-Security-Policy(CSP) の直し方
Content Security Policyは、ウェブサイトがすべての訪問者のブラウザに渡す安全のルールで、どのコードを実行してよいかを正確に伝えます。これがないと、悪意あるものが何らかの形でページに入り込んだ場合(コメント欄、ハッキングされたプラグイン、第三者スクリプトなどから)、ブラウザはそれを自由に実行します。鍵マークが出たまま、顧客が入力するカード番号やパスワードを静かに抜き取るコードも含めて。
あなたのビジネスにとっての結論: サイトが改ざんされると、悪意あるコードが、すべてが完全に正常に見える間に、あなた自身の決済画面から顧客の決済カードやログイン情報を直接読み取れます。チャージバック、不正請求の主張、報告対象の情報漏えい、そして大口顧客のセキュリティチームが商談を止める・潰すのに使う検査の不合格が残ります。
これで失いかねないもの
- 隠されたコードがページのひとつに忍び込み、顧客が決済時に入力するすべてのカード番号とパスワードを静かに複製して攻撃者に送ります。サイトは完全に正常に見え、不正の苦情が届いて初めて気づきます。
- 詐欺師があなたの本物のウェブサイトに偽の『ここで支払う』フォームを仕込み、自分の口座へ決済を捕らえます。顧客はあなたに払ったと思い、商品が来ないとあなたを責め、返金を要求します。
- 大口顧客のセキュリティチームがサイトをスキャンし、この基本的な保護がオフなのを見て指摘し、修正を証明できるまで契約を止める・失わせます。
- 標準的で無料の安全策の欠如に辿れる情報漏えいが報告対象のインシデントになります。規制当局の問い合わせ、顧客への通知、そして無料の修正よりはるかに高くつく評判の打撃。
なぜ重要か。 鍵マークはサイトへの接続が秘匿されていることを証明しますが、訪問者がページに来てからどのコードが実行されるかは制御しません。Content Security Policyはそれを行う安全策です。信頼する送信元から来ていないスクリプトを無視するようブラウザに指示し、改ざんされた1つのフィールド・広告・プラグインが、顧客のお金とデータを盗む道具に変えられないようにします。これはスコアカード上の評点付き検査で、相応の点に値し、プロのセキュリティ審査が最初に探すもののひとつです。
これは何か、平易に言うと
誰かがあなたのウェブサイトを訪れると、ブラウザはページをダウンロードし、そこにあるコードを何でも実行します—メニューを開き、ボタンを動かし、決済フォームを送信させるスクリプトなど。初期状態では、ブラウザはそのすべてを信頼します。どのコードが本当にあなたのもので、どれが誰かに忍び込まれたものかを知る術がないのです。
Content Security Policy(しばしばCSPと短縮)は、ウェブサイトがすべてのページに付ける短いルールのリストで、ブラウザにこう伝えます。『私が承認したこれらの送信元からのコードだけを実行し、それ以外はすべて拒否せよ。』 誰でも入れるナイトクラブと、入口にゲストリストのあるクラブの違いです。
これがこれほど重要な理由は、ウェブサイトが絶えず改ざんされるからです—必ずしもサーバーをハッキングするのではなく、ほとんどのサイトが開けっ放しにしている裏口を通じて。コメント欄、検索ボックス、古いプラグイン、広告や分析の第三者スクリプト、チャットウィジェットなど。攻撃者が自分のコードを1行でもあなたのページに乗せれば、ブラウザはそれをあなたのもののように実行します。そこから、顧客が入力するすべて—カード番号、パスワード、住所—を読み、静かにどこかへ送れます。Content Security Policyは、承認していない送信元からは何も実行しないことで、その扉を閉じます。
これが招きうる損失
抽象的な話ではありません。Content Security Policyが防ぐ攻撃—ページに注入され、あなた自身の顧客からデータを盗むコード—は、記録に残る最大級のカードスキミング情報漏えいの背後にあります。通常のビジネスではこう展開しがちです:
-
見えない決済スキマー。 攻撃者が、脆弱なプラグインや侵害された第三者スクリプトを通じて、決済ページに数行のコードを滑り込ませます。顧客が入力するすべてのカード番号・氏名・CVVがリアルタイムで複製され攻撃者に送られます。サイトは見た目も動作も完璧で、鍵マークもあります。発覚するのは数週間後、決済事業者がすべてあなたの店に辿れる不正報告の集中について電話してきたとき。今やチャージバック、強制的なセキュリティ監査、カード処理権限の喪失の可能性、そして法的に報告義務があるかもしれない情報漏えいに直面しています。
-
偽の決済フォーム。 詐欺師が、説得力のある『ここで支払う』ボックスを本物のウェブサイトに注入します。顧客はあなたのブランドを信じて情報を入力し、お金とデータは攻撃者へ。顧客はあなたを責め、それは間違っていません。あなたのサイトで起きたのですから。
-
失われた契約。 大口の見込み客のセキュリティチームが、ベンダーのデューデリジェンスの一環としてサイトを自動スキャンします。Content Security Policyがないことが即座に高重大度のギャップとして現れます。調達やセキュリティの審査担当には、その欠けた安全策ひとつが『この供給者は基本をやっていない』と読め、是正を求める間に商談が止まるか、合格した競合へ静かに移ります。
-
報告対象の情報漏えい。 データ侵害が、欠けている標準的で無料の安全策に辿られると、それは不運ではなく過失に見え始めます。規制当局の問い、顧客通知の義務、コスト—制裁金と、インシデントが収束した後も長く残る評判の損害—が変わります。
-
侵害された広告やウィジェット。 多くのサイトは外部から来るコード—広告ネットワーク、フォント、サポートチャット、分析—を読み込みます。そのどれかが侵害されると、悪意あるコードがまっすぐあなたのページに乗ります。Content Security Policyは、信頼する特定の外部送信元だけを許すことで爆発半径を制限し、ある供給者の侵害が自動的にあなたのものにならないようにします。
これの実体(詳細)
Content Security Policyは、ひとつのHTTPレスポンスヘッダー—ウェブサーバーがすべてのページとともに送る行—として配信されます。その値はディレクティブの集合で、それぞれコンテンツの種類とそれに許す送信元を名指しします。例えば:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'
平易に言えば、初期状態では自分のサイトからのものだけ読み込み、スクリプトは自分のサイトからのみ実行し、古いプラグインは許さず、他のサイトに自分をフレームで埋め込ませない、という意味です。
『良い』状態とは。 当社の検査はヘッダーの存在を見るだけではなく、セキュリティ審査担当のように、ポリシーをディレクティブごとに読み、実際にどれほど強いかを採点します。強いポリシーは:
- 制限的な基準(
default-src 'self')を設定し、本当に使う特定の信頼された第三者についてのみ広げます。 - 抜け穴を避けます。 スクリプトに
'unsafe-inline'や'unsafe-eval'を使わず、スクリプトにワイルドカード(*)や裸のスキーム送信元(https:など)を使いません—これらはポリシーが閉じるはずの扉を実質的に再び開きます。インラインスクリプトが本当に必要な場合は、nonceまたはハッシュを使い、承認した特定のコードだけが実行されるようにします。 frame-ancestors 'self'でフレーミングを締め(これは『顧客を騙すためにサイトを埋め込む』攻撃もブロックします)、object-src 'none'でレガシープラグインを無効にします。- report-onlyではなく強制です。
Content-Security-Policy-Report-Onlyヘッダーは監視するだけで、実行時の保護はゼロです。当社の検査はそれにごく一部の点しか与えず、決して合格として記録しません。ポリシーが強制されて初めて守られます。
存在しても'unsafe-inline'・'unsafe-eval'・ワイルドカードに頼るポリシーは依然として低い点になります—実際にはほとんど本当の保護を与えないからです。目標は厳密なポリシーであって、何でもいいポリシーではありません。
修正方法(無料・約1〜2時間)
IT担当やウェブサイトを運用している人にこれを渡してください。修正そのものは完全に無料です。 当社が料金をいただくのは、それが維持され正しい状態を保ち続けているかを監視する場合のみで、オンにすること自体には費用がかかりません。数分ではなく1〜2時間かかるのは、自分のサイトの一部を誤ってブロックしないための慎重な試行ステップのためです。
-
report-onlyモードで始める—まだ強制しない。
Content-Security-Policy-Report-Onlyレスポンスヘッダーを追加します。これは実際にはブロックせず、ブロックされるであろうものを監視・記録するので、各ページが本当に何に依存しているかを学ぶ間、ライブサイトは動き続けます。(重要:report-only単独では訪問者に保護を与えません。安全な最初の一歩にすぎません。) -
サイトが実際に使うものからポリシーを組み立てる。 レポートを見て、スクリプト・スタイル・フォント・画像のすべての正規の送信元—自分のドメイン、分析、決済事業者、フォントのホスト、チャットウィジェット—を見つけ、許可された送信元として列挙します。手堅い出発点は
default-src 'self'に、本当に使う信頼された第三者の明示的なエントリを加えたものです。 -
目的を台無しにする抜け穴を避ける。 スクリプトの
'unsafe-inline'と'unsafe-eval'を避け、スクリプトのワイルドカード(*)や裸のスキーム(https:)を避けます—これらはポリシーが閉じるはずのまさにそのギャップを再び開きます。インラインスクリプトが避けられない場合は、nonceまたはハッシュを使い、承認した特定のコードだけが実行されるようにします。 -
フレーミングとプラグインを締める。
frame-ancestors 'self'を追加し(これは他のサイトがあなたを埋め込んで顧客を騙すのも止め、関連するクリックジャッキング検査も満たします)、object-src 'none'でレガシーのプラグインベース攻撃をブロックします。 -
report-onlyから強制へ切り替える。 レポートがきれいでサイトが動いたら、ヘッダー名を
Content-Security-Policy-Report-OnlyからContent-Security-Policyに変えます。これが実際に保護をもたらすステップです—report-onlyのポリシー単独ではもたらさず、検査にも合格しません。ヘッダーを設定する場所はプラットフォーム次第:
- Cloudflare: Rules → Transform Rules → Modify Response Header →
Content-Security-Policyを設定。(report-onlyの試行にもCloudflareを使えます。) - Nginx:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" always; - Apache:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" - IIS(web.config):
Content-Security-Policyという名前のカスタムHTTPレスポンスヘッダーを、その値にポリシーを設定して追加します。 - Google Workspace / Microsoft 365: これらはメールを動かすもので公開ウェブサイトではないので、ポリシーはウェブサイトが実際にホストされている場所(上のCloudflareやウェブホスト)で設定し、メールの管理画面では設定しません。
- Cloudflare: Rules → Transform Rules → Modify Response Header →
-
ドメインを再チェックし、ポリシーがオンで強制されており、弱める抜け穴がないことを確認します。
よくある間違い
- report-onlyで止める。 最もよくある誤り。ポリシーがreport-onlyモードで追加され、皆が次へ進み、サイトは実際には決して守られない。report-onlyは何もブロックしません。強制に切り替えなければなりません。
- 『とにかく動かす』ために
'unsafe-inline'に手を伸ばす。 ポリシーが正規のインラインスクリプトをブロックしたとき、手早い修正はすべてのインラインスクリプトを許すことですが—それはポリシーが閉じるはずだったまさにその穴を再び開きます。代わりにnonceやハッシュを使いましょう。 - ワイルドカードを使う。
script-srcに裸の*(やhttps:)があると、どこからでもスクリプトを許すことになり、ポリシーはほとんど本当の保護を与えず、依然として低い点になります。 - 第三者の送信元を忘れる。 使っている正規の外部サービス(分析、フォント、決済ウィジェット)をまず列挙せずに厳格なポリシーを強制すると、自分のサイトの一部が壊れることがあります—まさにそれがreport-only試行ステップが存在する理由です。
- ホームページだけに設定する。 ポリシーはすべてのページ、特に決済・ログイン・アカウントのページをカバーする必要があります—それらが攻撃する価値のあるページです。
- 鍵マークの代わりとして扱う。 Content Security PolicyとHTTPS/HSTSは守るものが違います。すべてが必要で、ひとつが他の代わりにはなりません。
よくある質問
技術に詳しくありません。自分で対応できますか?
細かいことを理解する必要はありません。これはウェブサイトやホスティングを運用している人が追加する設定で、Cloudflareのようなサービスでは大部分が案内されます。下の『修正方法』の項を渡してください。無料です。唯一の注意は、自分のサイトの一部を誤ってブロックしないよう、まず監視のみの試行で慎重に展開すべきことで、まさにその手順をカバーしています。
すでに鍵マークとSSL証明書があります。サイトは安全では?
鍵マークはページの配信を守りますが、その中で何が実行されるかは取り締まりません。悪意あるコードが何らかの形でページに行き着けば(ハッキングされたプラグイン、侵害された広告、注入されたフィールド経由で)、鍵マークはそれがデータを盗むのを止めません。Content Security Policyは、そもそも何が実行を許されるかを制限する層です。守るものが違うので、両方が必要です。
これをオンにするとサイトが壊れませんか?
一気に激しくオンにすると壊れることがあります。実際に使っている正規のスクリプトをブロックしかねないからです。だから標準的な手順は、ブロックせず監視する『report-only』試行モードで始め、指摘されたものを直し、その後にのみ強制することです。この方法なら安全で、試行ステップは下の修正に組み込まれています。
すでに『report-only』モードにしました。守られていますか?
いいえ、これが最もよくある偽りの安心感です。report-onlyモードはブロックされるであろうものを監視・記録しますが、何もブロックしません。訪問者への実際の保護はゼロです。安全な最初の一歩にすぎません。当社の検査はreport-onlyに実際のポリシーのごく一部の点しか与えず、合格として記録しません。強制モードに切り替えて初めて守られます。
これは評点に影響しますか、それとも助言だけですか?
評点に影響します。Content Security Policyの検査は評点付きで、ウェブセキュリティのカテゴリーで最大25点に値します。欠けている・弱いポリシーは高重大度と表示され、評点を引き下げます—まさに顧客のセキュリティ質問票が尋ねる類のギャップです。
開発者がポリシーを追加したのに評点がまだ低いのはなぜ?
ポリシーは存在しても弱いことがあります。最もよくある犯人は、スクリプトの『unsafe-inline』や『unsafe-eval』、あるいはワイルドカードの送信元(裸の*)などの抜け穴で、ポリシーが閉じるはずだったまさにそのギャップを再び開きます。当社の検査はポリシーをディレクティブごとに読み、それらの弱点を減点します—何でも許すポリシーは、ないのとほとんど変わらない点しか取れません。修正は、それらの抜け穴の代わりにnonceやハッシュを使ってスクリプトのルールを厳しくすることです。