こんにちは、決済サービスの開発を担当している児玉です。
みなさんCSP(Content Security Policy)という言葉を聞いたことはありますでしょうか?
正直、私自身はこの決済サービスの開発に携わるまでは、ほとんど意識したことがありませんでした。
ですが、カード情報を扱う決済サービスではセキュリティ強化が不可欠で、その中でも重要な仕組みがこのCSPです。
今回は、なぜCSPが必要なのか、どんなメリットがあるのかを分かりやすく解説していきます。
1. CSP(Content Security Policy)とは?
■ ブラウザが「何を読み込めるか」をコントロールする仕組み
CSP(Content Security Policy)とは、Webページを表示するブラウザが「どのドメインから、どの種類のリソース(スクリプトや画像など)を読み込んでよいか」を制限できる仕組みです。
たとえば「自社ドメインのJavaScriptファイルだけ許可する」「画像は自社とCDNのみ読み込める」といったルールを決めると、ルールに合わない外部スクリプトやファイルは自動的にブロックされます。
■ なぜ決済サービスでCSPが必要なの?
クレジットカード情報の流出リスクを下げる
決済ページが悪意あるスクリプトに改ざんされると、ユーザーが入力したカード情報が盗まれてしまう可能性があります。
CSPを導入しておくと、不正なドメインから読み込まれるスクリプトをブロックできるので、こうした改ざん攻撃(Magecartなど)のリスクを大幅に低減できます。
PCI DSSなどのセキュリティ標準にも関連
クレジットカード業界のセキュリティ標準「PCI DSS」では、バージョン4.0から決済ページ上のスクリプト管理に関する要件が追加され、その遵守が厳格に求められています。CSPはその要件を満たす一つの有効な手段として認知されつつあります。
2. どんな攻撃を防げるの?
■ 不正スクリプトの埋め込み(スキミング攻撃)
スキミング攻撃やクロスサイトスクリプティング(XSS)では、外部から悪意あるスクリプトを読み込む形でサイトを改ざんされることがあります。
しかしCSPを設定しておけば「許可していないドメインからのスクリプト」は一切ブロックされるため、攻撃者が勝手に仕込んだコードが動かなくなるわけです。
■ データの無断送信
もし仮に攻撃者がスクリプトを動かせたとしても、CSPの設定で「外部サーバへの通信先(connect-src)」を制限していれば、勝手に外部へユーザーの入力データを送ることは難しくなります。
これによって、機密情報の流出を未然に防ぐ効果も期待できます。
3. CSPの基本設定イメージ
CSPはHTTPレスポンスヘッダ(Content-Security-Policy:)か、HTMLの<meta>タグでブラウザに指示を出します。
たとえば、以下のように設定すると「スクリプトは自社ドメインのみ読み込み可、画像も自社ドメインからだけ」というポリシーを示せます。
Content-Security-Policy: default-src 'none'; script-src 'self'; img-src 'self'; style-src 'self'; connect-src 'self'; ...
default-src 'none'まずは基本的にすべてのリソース読み込みをブロックする
script-src 'self'スクリプトは「自分のサイト('self')」のみ許可
img-src 'self'画像も自分のサイトのみ許可
connect-src 'self'XHRやFetchの送信先も自分のサイトだけ許可
これにより、知らないドメインや怪しい外部サイトからは何も読み込めなくなります。
4. よく使われるディレクティブ一覧
CSPにはさまざまな「ディレクティブ(命令)」があります。よく使われるものをまとめると、下記のようになります。
| ディレクティブ | 意味・役割 | 例 |
|---|---|---|
| default-src | すべてのリソースに対するデフォルトの許可・拒否設定 | 'none'/'self' |
| script-src | JavaScriptの読み込み元を指定 | 'self' https://js.example.com |
| style-src | CSSの読み込み元を指定 | 'self' 'nonce-abc123' |
| img-src | 画像の読み込み元を指定 | 'self' data: |
| connect-src | XHR/Fetch/WebSocketの送信先を指定 | 'self' https://api.example.com |
| frame-src | iframeの読み込み先を限定 | 'self' https://iframe.example.com |
| object-src | Flashやプラグインなどの許可設定 | 'none' |
| report-uri | 違反があった場合に報告するURL | https://report.example.com/csp-violation |
| nonce, hash | インラインスクリプトを限定的に許可する仕組み | 'nonce-XXXXXXXX' or 'sha256-XXXX' |
5. 導入時のポイント
- 最初は“Report-Onlyモード”でテスト
- いきなりブロックを有効化すると正常な機能まで動かなくなる恐れがあります。
- まずは
Content-Security-Policy-Report-Only:ヘッダを設定し、違反レポートを収集しながら問題の有無を確認しましょう。
- インラインスクリプトは避ける or nonce/hashを使う
- 厳格なCSPでは、インラインで書かれたJSは基本ブロックされます。
- もしどうしてもインラインで使う必要がある場合、
nonceを付与して特定のスクリプトだけ許可する方法があります。
- 外部ライブラリの改ざん防止策:SRI (Subresource Integrity)
- CDNなどから読み込むファイルが改ざんされていないかチェックする仕組みです。
<script src="~" integrity="sha256-XXX" crossorigin="anonymous"></script>のように設定し、CSPと合わせて使うことでより安全性が高まります。
6. まとめ
- CSP(Content Security Policy)は、決済ページなどにおける不正スクリプトの実行を防ぐ大切な仕組み。
- 導入時には、スクリプトの棚卸し・Report-Onlyモードでの事前チェック・SRIなど追加対策がポイント。
もしCSPをこれから導入される方は、まずは自社で使われているスクリプトをしっかり洗い出し、Report-Onlyモードで試してみてはいかがでしょうか?
これを機に、「どうやってサービスを守るか」をエンジニアみんなで考える文化が育つとさらに良いですね。
We are hiring!!
ROBOT PAYMENTでは一緒に働く仲間を募集しています!!!