Cloudflare Page Shield
Web 通信を Cloudflare 経由にすることで、Cloudflare が Content Security Policy レスポンスヘッダ や Content-Security-Policy-Report-Only レスポンスヘッダ を付与し、ページ内のスクリプトやコネクションを監視したり、AllowList で運用できる製品です。
こうした機能は、以下のような Magecart Attack に対して有効な対策のひとつです。
Code change alert
今回はこの機能を検証します。
サイトが使用する JavaScript に意味のある変更があった場合、アラートを受信します。
Code change alert · Cloudflare Page Shield docs
Available as a paid add-on for Cloudflare customers on an Enterprise plan.
Page Shield New Code Change Detection Alert: Triggered daily by any changed JavaScript dependencies detected in your pages.
サンプルスクリプト
以下のスクリプトを使います。
-
custom.js
- Hash =
a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027
- Hash =
ダウンロードは以下のコマンドで実行できます。
sudo curl -s https://www.sweatybetty.com/on/demandware.static/-/Library-Sites-sweatybettylibrary/en_US/v1574703272172/js/custom.js \
-o /var/www/html/js/custom.js
-
injected_code.js
- Hash =
e51845a7756eb729efd9d5b54c681deb5178f69bd051c6dcaa2e9562ff68fe47
- Hash =
ダウンロードは以下のコマンドで実行できます。
sudo curl -s https://raw.githubusercontent.com/geeksonsecurity/js-malicious-dataset/master/legitimate-injected/1/injected_code.js \
-o /var/www/html/js/injected_code.js
通知設定
Page Shield New Code Change Detection Alert のメール通知を設定します。
.js
をキャッシュしない設定
Javascript の変更を検知させるため、キャッシュしない設定にしておきます。
- When incoming requests match…
(http.request.uri.path.extension eq "js")
キャッシュする設定の場合は、Javascript の変更を検知させるためには都度キャッシュパージしてください。
キャッシュする設定の場合は、Auto Minify によってハッシュ値が変わる可能性があるため、ご注意ください。
参考:Purge Everything
参考:Single File Purge
ページ準備
custom.js
の中身を code-change-alert-test00.js
として以下のように配置し
sudo curl -s https://www.sweatybetty.com/on/demandware.static/-/Library-Sites-sweatybettylibrary/en_US/v1574703272172/js/custom.js -o /var/www/html/js/code-change-alert-test00.js
以下の HTML を用意します。
<!doctype html>
<title>Code Change Alert Test</title>
<body>
<h1>Code Change Alert Test</h1>
<script src="js/code-change-alert-test00.js"></script>
</body>
</html>
ブラウザアクセス
準備したページにブラウザでアクセスし、CSP レポートを Page Shield に送信します。
Page Shield Script Monitor にレポートするためには、content-security-policy-report-only
レスポンスヘッダが Cloudflare によって付与される必要があります。
サンプリングが適用されるため、付与される割合は 10〜20回に1回程度のようです。
そのため、Page Shield に CSP レポートを1回だけ送信できる以下の puppeteer
によるスクリプトを使います。
Chrome
your-domain.example.com
の部分を適宜変更して使います。
--short-reporting-delay
により CSP レポートがすぐに送られます。
Developer Tools がうまく表示されない場合は「Option (Alt) + R」で何回か Developer Tools をリロードしてみてください。
Developer Tools がうまく表示されない場合でも、CSP レポートは問題なく送られます。
以下のように実行し Status: Success
となれば、CSP レポートが正常に送られたことが確認できます。
Firefox
your-domain.example.com
の部分を適宜変更して使います。
以下のように実行し Status: 200
となれば、CSP レポートが正常に送られたことが確認できます。
Developer Tools では手動で Network
タブから Other
に絞ると Initiator csp
による POST リクエストを確認できます。
Reported Script の確認
以下のコマンドで最新の Reported Script を確認できます。
1回目
ブラウザアクセスのスクリプトを1回実行させた結果です。
versions
に値がないため、再度実行します。
-
"status": "infrequent"
(Added) -
"first_seen_at": "2023-08-02T02:32:17Z"
(Added) -
"last_seen_at": "2023-08-02T02:32:17Z"
(Added) -
"versions": null
(Added)
{
"id": "311a9beaf4a04bb8b584fb449c3684c1",
"url": "https://code-change-alert.example.com/js/code-change-alert-test00.js",
"added_at": "0001-01-01T00:00:00Z",
"first_seen_at": "2023-08-02T02:32:17Z",
"last_seen_at": "2023-08-02T02:32:17Z",
"host": "code-change-alert.example.com",
"domain_reported_malicious": null,
"malicious_domain_categories": [],
"url_reported_malicious": null,
"malicious_url_categories": [],
"first_page_url": "https://code-change-alert.example.com/pageshieldforcecsp00.html",
"status": "infrequent",
"url_contains_cdn_cgi_path": false,
"versions": null
}
2回目
ブラウザアクセスのスクリプトを2回実行させた結果です。
versions
に情報が入り、last_seen_at
から1分以内に fetched_at
されたことがわかります。
hash
の値も custom.js
の中身であることを示します。
-
"status": "infrequent"
(No update) -
"first_seen_at": "2023-08-02T02:32:17Z"
(No update) -
"last_seen_at": "2023-08-02T02:34:50Z"
(Updated) -
"fetched_at": "2023-08-02T02:35:34Z"
(Added) -
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027"
(Added)
{
"id": "311a9beaf4a04bb8b584fb449c3684c1",
"url": "https://code-change-alert.example.com/js/code-change-alert-test00.js",
"added_at": "0001-01-01T00:00:00Z",
"first_seen_at": "2023-08-02T02:32:17Z",
"last_seen_at": "2023-08-02T02:34:50Z",
"host": "code-change-alert.example.com",
"domain_reported_malicious": null,
"malicious_domain_categories": [],
"url_reported_malicious": null,
"malicious_url_categories": [],
"first_page_url": "https://code-change-alert.example.com/pageshieldforcecsp00.html",
"status": "infrequent",
"url_contains_cdn_cgi_path": false,
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027",
"js_integrity_score": 1,
"obfuscation_score": 93,
"dataflow_score": 1,
"fetched_at": "2023-08-02T02:35:34Z",
"versions": [
{
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027",
"js_integrity_score": 1,
"obfuscation_score": 93,
"dataflow_score": 1,
"fetched_at": "2023-08-02T02:35:34.984506Z",
"is_malicious_code": true
}
]
}
コード変更する
ここで code-change-alert-test00.js
の中身を injected_code.js
に変更します。
sudo curl -s https://raw.githubusercontent.com/geeksonsecurity/js-malicious-dataset/master/legitimate-injected/1/injected_code.js \
-o /var/www/html/js/code-change-alert-test00.js
3回目
ブラウザアクセスのスクリプトを3回実行させた結果です。
last_seen_at
のみ更新されたことがわかります。再度実行します。
-
"status": "infrequent"
(No update) -
"first_seen_at": "2023-08-02T02:32:17Z"
(No update) -
"last_seen_at": "2023-08-02T02:38:47Z"
(Updated) -
"fetched_at": "2023-08-02T02:35:34Z"
(No update) -
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027"
(No update)
{
"id": "311a9beaf4a04bb8b584fb449c3684c1",
"url": "https://code-change-alert.example.com/js/code-change-alert-test00.js",
"added_at": "0001-01-01T00:00:00Z",
"first_seen_at": "2023-08-02T02:32:17Z",
"last_seen_at": "2023-08-02T02:38:47Z",
"host": "code-change-alert.example.com",
"domain_reported_malicious": null,
"malicious_domain_categories": [],
"url_reported_malicious": null,
"malicious_url_categories": [],
"first_page_url": "https://code-change-alert.example.com/pageshieldforcecsp00.html",
"status": "infrequent",
"url_contains_cdn_cgi_path": false,
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027",
"js_integrity_score": 1,
"obfuscation_score": 93,
"dataflow_score": 1,
"fetched_at": "2023-08-02T02:35:34Z",
"versions": [
{
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027",
"js_integrity_score": 1,
"obfuscation_score": 93,
"dataflow_score": 1,
"fetched_at": "2023-08-02T02:35:34.984506Z",
"is_malicious_code": true
}
]
}
4回目
ブラウザアクセスのスクリプトを4回実行させた結果です。
"status": "active"
となり、再度 fetched_at
されたことがわかります。
hash
の値が変更となり、versions
でも履歴が確認できます。
-
"status": "active"
(Updated) -
"first_seen_at": "2023-08-02T02:32:17Z"
(No update) -
"last_seen_at": "2023-08-02T02:42:21Z"
(Updated) -
"fetched_at": "2023-08-02T02:43:26Z"
(Updated) -
"hash": "e51845a7756eb729efd9d5b54c681deb5178f69bd051c6dcaa2e9562ff68fe47"
(Updated)
{
"id": "311a9beaf4a04bb8b584fb449c3684c1",
"url": "https://code-change-alert.example.com/js/code-change-alert-test00.js",
"added_at": "0001-01-01T00:00:00Z",
"first_seen_at": "2023-08-02T02:32:17Z",
"last_seen_at": "2023-08-02T02:42:21Z",
"host": "code-change-alert.example.com",
"domain_reported_malicious": false,
"malicious_domain_categories": [],
"url_reported_malicious": false,
"malicious_url_categories": [],
"first_page_url": "https://code-change-alert.example.com/pageshieldforcecsp00.html",
"status": "active",
"url_contains_cdn_cgi_path": false,
"hash": "e51845a7756eb729efd9d5b54c681deb5178f69bd051c6dcaa2e9562ff68fe47",
"js_integrity_score": 5,
"obfuscation_score": 5,
"dataflow_score": 99,
"fetched_at": "2023-08-02T02:43:26Z",
"versions": [
{
"hash": "e51845a7756eb729efd9d5b54c681deb5178f69bd051c6dcaa2e9562ff68fe47",
"js_integrity_score": 5,
"obfuscation_score": 5,
"dataflow_score": 99,
"fetched_at": "2023-08-02T02:43:26.821194Z",
"is_malicious_code": true
},
{
"hash": "a991b04c6a5b3f800629782e47491ea6581b11df683c17e1df54510d15114027",
"js_integrity_score": 1,
"obfuscation_score": 93,
"dataflow_score": 1,
"fetched_at": "2023-08-02T02:35:34.984506Z",
"is_malicious_code": true
}
]
}
Code change alert の確認
上記の内容でコード変更が検知されたことが確認できました。
Code change alert は1日1回、日本時間 8:30 AM 前後に通知が来ます。
メール
Webhook
まとめ
今回は一部の機能を確認しましたが、全体としては PCI DSS v4.0 や業界・政府による要請など、CSP を活用した対策が今後も必要になる場面があると思います。
消費者ブラウザに読み込まれる決済ページスクリプトの管理が新たに求められるようになった。
対策としてコンテンツセキュリティポリシー(CSP)を使用して決済ページスクリプトが未承認のコンテンツに置き換えられるのを防ぐ、サブリソースの整合性(SRI)によってスクリプトが改竄されていないことの検証を行う、などが挙げられる。
Cloudflare Page Shield では他にも機能を拡充しているので、ぜひ検討してみてはいかがでしょうか。