GTM(Google タグマネージャー)で GA4 や各種計測タグの実装をご担当されている方、こういう状況に遭遇したことはないでしょうか。
- GTM のプレビューモードではタグが発火しているのに、 GA4 DebugView にイベントが届かない
- カスタム HTML タグだけがなぜか反応しない
- 「dataLayer.push したはずなのに、 dataLayer に何も入っていない」
- ブラウザのコンソールには見慣れない英語のエラーメッセージ
こうした症状の背景に多いのが、 CSP(Content Security Policy) と呼ばれるブラウザのセキュリティ機構です。普段はサイト側のエンジニアが管理する領域なので、計測担当者からはなかなか見えにくい存在。ところが、その挙動が計測タグの動作可否に直接影響することがあります。
この記事では、 CSP とは?を非エンジニアの視点で整理し、 GTM の各機能との関係を解きほぐしたうえで、トラブル発生時の調べ方と対処法の選択肢までを一通り押さえます。読み終わるころには「CSP の制約で計測タグが動かなくなっている状況」を自分で見抜けて、エンジニアと建設的な会話ができる状態になっているはずです。
CSP は他人事ではなくなりつつある
「自分の担当サイトでは特に問題なく動いているし、 CSP なんて関係ない」と感じている方も多いかもしれません。確かに、データで見ても CSP は全世界の Web サイトの一部にしか導入されていません。
HTTP Archive が毎年公開している Web Almanac の 2025 年版によると、 CSP ヘッダーを送信しているサイトの割合は約 22%。 2021 年の約 12% から右肩上がりで増えてはいるものの、依然として 8 割近いサイトはまだ CSP を導入していません 。(Part II Chapter 9 Security https://almanac.httparchive.org/en/2025/security Date published: Jan 15, 2026 )
ただし、ここで注目したいのは「どんなサイトに CSP が入っているか」という分布です。 SharePoint Online、 Salesforce、 ServiceNow、 Microsoft 365、各種エンタープライズ SaaS、大企業のイントラ系業務システム。こうした業務用途のプラットフォームでは、 CSP はすでに標準装備と言ってよい状態。
つまり、コーポレートサイトやランディングページしか触らない計測担当者にとっては縁遠い話でも、 エンタープライズ案件や業務系プラットフォーム上の計測 を扱う立場になった途端、 CSP は避けて通れない関門になります。今後 CSP の採用率はさらに上がっていく見込みなので、知識として持っておく価値は十分にあります。

出所: https://almanac.httparchive.org/en/2025/security
CSP とは何か
CSP の正式名称は Content Security Policy 、直訳すると「コンテンツのセキュリティに関する方針」。ブラウザに対してサイト側から「うちのサイトではこの種類の JavaScript だけ実行してください」と指示する仕組みです。
歴史をざっくり言うと、 2009 年ごろに Mozilla を中心に提案され、 2012 年に W3C の正式仕様(CSP Level 1)となり、 2013 年から Chrome や Firefox で標準サポートが始まりました。約 15 年の歴史を持つ Web 標準ということになります。
CSP の本来の目的は、 XSS(クロスサイト・スクリプティング)と呼ばれる攻撃を防ぐこと。攻撃者が掲示板の投稿欄やコメント欄に悪意のあるスクリプトを紛れ込ませて、それを読んだ他のユーザーのブラウザで実行させる。そうした攻撃をブラウザ側でブロックするための、防御層として CSP が設計されています。
計測担当者の視点だと CSP は計測の制約として現れる瞬間もありますが、本来はサイト利用者を守る防御機構。 CSP が整備されているサイトほど、利用者にとっては安全に使えるサイトであるとも言えます。
CSP はどこに書かれているか

CSP の設定内容は、 サーバーがブラウザに送る HTTP レスポンスヘッダー の一項目として届きます。 HTML ファイルとは別の経路で送られる、いわば「封筒に添えられたルール表」のような存在。
ブラウザはこのルール表を最初に受け取り、その後 HTML を解釈する過程で「このスクリプトは許可されているか」と都度照合します。許可されていないスクリプトは実行しない、というのが CSP の基本動作。
例外的に HTML の <meta> タグで CSP を宣言する方法もありますが、ヘッダー方式が主流かつ安全(攻撃者が改ざんしにくい)とされています。
CSP のルールの読み方
実際の CSP は、こんな見た目をしています。
Content-Security-Policy: script-src ‘self’ https://www.googletagmanager.com ‘unsafe-eval’; img-src ‘self’ https:; connect-src ‘self’ https://www.google-analytics.com
長くて圧倒されるかもしれませんが、構造はシンプル。 ディレクティブ + 値 のペアが、セミコロン区切りで並んでいるだけです。
ディレクティブとは

ディレクティブ(directive)は直訳すると「指令」「指示」。 CSP の文脈では「何について制御するか」を示す項目名のことです。
警備マニュアルにたとえると、ディレクティブは「章タイトル」のような存在。「来訪者の対応について」「荷物の検査について」「通信機器の使用について」というように、テーマごとに章が分かれている。 CSP もそれと同じで、「JavaScript について」「画像について」「通信について」と、リソースの種類ごとにディレクティブが用意されています。
計測担当者がよく出会うディレクティブは以下の通り。
| ディレクティブ | 何を制御するか | 計測との関係 |
| script-src | JavaScript の読み込み・実行 | 最重要。 GTM やカスタム HTML はここに依存 |
| connect-src | fetch、 XHR、 WebSocket などの通信先 | GA4 のイベント送信先がここで許可されている必要 |
| img-src | 画像の読み込み元 | ピクセル計測タグ(1×1 画像)はここ |
| frame-src | iframe で埋め込めるサイト | 広告タグやチャットウィジェットで関係あり |
| default-src | 個別指定がないものの既定値 | 上記のいずれかが未指定のときの保険 |
計測タグまわりで一番重要なのは、なんといっても script-src です。
script-src の値: 3 種類の許可方式

script-src の値には、 3 種類の異なる許可方式があります。それぞれが「どんな届き方をした JavaScript を許可するか」を表しています。
(1) URL / ドメイン指定
script-src https://www.googletagmanager.com
「この URL から読み込まれた JavaScript ファイル(外部スクリプト)は実行 OK」という意味。 <script src=”…”> の形でファイルを読み込むパターンが該当します。最も安全な方式。
(2) ‘unsafe-inline’
script-src ‘unsafe-inline’
「HTML に直接書かれたスクリプト(インラインスクリプト)も実行 OK」という意味。具体的には、
- <script>alert(‘hi’)</script> のように HTML の中に直接書かれたコード
- <button onclick=”…”> のように HTML 属性に書かれたコード
- JavaScript で後から HTML に追加されたスクリプトタグ
これらすべてを許可するキーワード。 XSS のリスクが上がるため、セキュリティ意識の高いサイトほど ‘unsafe-inline’ は許可しない方向 で運用しています。
(3) ‘unsafe-eval’
script-src ‘unsafe-eval’
「eval() や new Function() のような、 文字列をプログラムに変換して実行する処理 を許可する」という意味。これも本来は危険な機能ですが、 GTM をはじめ多くの計測ツールが内部で使うため、許可されているサイトは比較的多い印象。
‘unsafe- シリーズの意味
‘unsafe-inline’ も ‘unsafe-eval’ も、頭に ‘unsafe-‘ が付いています。これは設計者からの「安全じゃないけど、必要なら使ってください」という警告ニュアンスを含む接頭辞。
つまり、これらのキーワードを CSP に含めること自体が、「安全性を一段下げる代わりに利便性を取る」という妥協を意味しています。
GTM の各タグタイプを解剖する
CSP の用語を一通り押さえたところで、本題の GTM 側の話に入ります。 GTM の各機能が「どんな実行方式で動いているか」を理解すると、 CSP との関係が一気に見通せるようになります。
GTM の構成要素
GTM コンテナの中身を整理すると、次のような構造になっています。
- gtm.js(本体) : Google のサーバー(www.googletagmanager.com)から読み込まれる外部 JavaScript ファイル
- タグ : 計測やマーケティング処理を実行する単位(GA4 イベントタグ、カスタム HTML タグ等)
- トリガー : タグを発火させる条件(ページビュー、クリック、カスタムイベント等)
- 変数 : タグやトリガーで使う動的な値
このうち CSP との相性が問われるのは、 gtm.js 本体の読み込みと、各タグの実行方式です。
タグタイプは大きく分けて 4 種類
GTM のタグタイプは大別すると以下の 4 種類。
- 標準タグ : GA4 イベント、 Google タグ、 Floodlight などの既製品
- コミュニティテンプレート : GTM ギャラリーから検索してインポートできる第三者製テンプレート
- カスタムテンプレート : テンプレートエディタで自作するもの
- カスタム HTML タグ : 自由に <script> を書ける万能枠
このうち今回の話の主役になるのは カスタム HTML タグ 。万能枠であるがゆえに、 CSP と最も衝突しやすい存在でもあります。
タグタイプ別の実行方式と CSP 要件

ここが本記事の核心。各タグタイプの実行方式を整理すると、以下のような構造になっています。
| GTM の要素 | 実行方式 | 必要な CSP |
| gtm.js(本体) | 外部ファイル読み込み | script-src に www.googletagmanager.com |
| 標準タグ(GA4 等) | gtm.js 内部で関数を実行、 fetch / sendBeacon で送信 | ‘unsafe-eval’ + connect-src |
| カスタム JavaScript 変数 | gtm.js 内部で new Function() で評価 | ‘unsafe-eval’ |
| カスタム HTML タグ | 新しい <script> タグを DOM に注入 | ‘unsafe-inline’ |
| カスタムテンプレート | サンドボックス内で実行 | ‘unsafe-eval’ |
| コミュニティテンプレート | カスタムテンプレートと同じ | ‘unsafe-eval’ |
注目すべきは、 カスタム HTML タグだけが ‘unsafe-inline’ を要求している という点です。他の機能は ‘unsafe-eval’ で動くため、 GTM を使うサイトであれば自然に許可されているケースが多い。一方でカスタム HTML タグだけは、 ‘unsafe-inline’ が許可されていないサイトでは実行されません。
なぜカスタム HTML タグだけ別格なのか

カスタム HTML タグは、ユーザーが書いた HTML(<script> タグを含む)を、 GTM が発火タイミングで ページの DOM に後から差し込む という動作をします。
具体的には、 GTM 本体が概念的に以下のような処理を実行します。
タグの中身 = “<script>alert(‘hello’)</script>”
document.body に append する
差し込まれた <script> タグは、ブラウザから見ると HTML に直接書かれたスクリプトと同じ扱い。つまりインラインスクリプトに分類されるため、 ‘unsafe-inline’ の許可が必要になります。
GTM 本体自体は外部ファイルとして信頼されている一方、 GTM 本体が 後から注入しようとする <script> は CSP の判定対象として別物として扱われる、という構造。ここがハマりどころの正体です。
一方、標準タグやカスタムテンプレートは新しい <script> タグを生成しません。 gtm.js 本体の中で関数として処理が完結するため、 ‘unsafe-inline’ を必要としない、というわけです。
計測が動かないときの調べ方

ここまでで CSP と GTM の関係性は整理できたので、次はトラブル時の実践的な調査手順を見ていきます。
ステップ 1: ブラウザのコンソールを開く
問題のサイトを開いた状態で、 F12 キーを押して DevTools(開発者ツール)を起動。 Console タブを選びます。
CSP の判定でスクリプトの実行が許可されなかった場合、特徴的なエラーメッセージが表示されます。
Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self’ ‘unsafe-eval'”. Either the ‘unsafe-inline’ keyword, a hash (‘sha256-…’), or a nonce (‘nonce-…’) is required to enable inline execution.
Refused to execute inline script や Content Security Policy directive というフレーズが出ていれば、 CSP が原因と確定。さらにエラーメッセージの後半に、 どのディレクティブの何が足りないか(この例では ‘unsafe-inline’ か hash か nonce)まで丁寧に書いてあります。
ステップ 2: サイトの CSP 設定を確認する
エラーが出ている場合、次はサイトの CSP 設定そのものを確認します。確認方法は 3 つ。
方法 1: DevTools の Network タブ(推奨)
- DevTools の Network タブを開く
- ページを再読み込み(F5)
- リクエスト一覧の 一番上にある HTML ドキュメント本体のリクエスト(URL がページのアドレスと同じもの)をクリック
- 右側パネルの Headers タブを選ぶ
- Response Headers セクションで Content-Security-Policy を探す
ここに表示される長い文字列が、そのページに適用されている CSP の中身。
方法 2: HTML 内の <meta> タグを確認
サーバーヘッダーではなく HTML 側で CSP を宣言しているケースもあります。ページを右クリックして「ページのソースを表示」を選び、 <meta http-equiv=”Content-Security-Policy”> を検索。
方法 3: 外部チェックツールを使う
URL を入れるだけで CSP の中身と評価を取得できる Web サービスがあります。サイトの管理権限がなくても誰でも使えます。
- Mozilla Observatory : https://observatory.mozilla.org
- Google CSP Evaluator : https://csp-evaluator.withgoogle.com
- securityheaders.com : https://securityheaders.com
特に Google CSP Evaluator は、 CSP の各ディレクティブごとに「ここが弱い」「ここが脆弱」と具体的に指摘してくれるので便利です。
ステップ 3: CSP の中身を読み解く
仮にあるサイトの CSP がこうだったとします。
script-src ‘self’ https://www.googletagmanager.com ‘unsafe-eval’ https://www.google-analytics.com
ここから読み取れることは:
- 自サイト(‘self’)の JavaScript は OK
- GTM(googletagmanager.com)からのスクリプトは OK
- GA(google-analytics.com)からのスクリプトは OK
- eval 系の処理も OK(‘unsafe-eval’ あり)
- しかし ‘unsafe-inline’ は無いので、カスタム HTML タグは実行されない
ここで先ほどの「タグタイプ別の実行方式」の表と照らし合わせると、原因が一発で特定できます。
対処法の選択肢
原因が CSP だと分かったら、次は対処法を考えるフェーズ。状況に応じて複数の選択肢があります。
案 1: サイト側で CSP を緩める
最もシンプルな案。サイトの CSP に ‘unsafe-inline’ を追加してもらえば、既存のカスタム HTML タグはそのまま動きます。
メリット
- GTM 側の改修が不要
- 最短で問題解決
デメリット
- サイト全体のセキュリティが下がる(XSS のリスクが上がる)
- 自社サイトでも、セキュリティ部門の承認が下りにくいケースが多い
- 受託案件では顧客側の運用ポリシーで却下されがち
現実性
自分でサイト管理権限を持っていて、かつセキュリティ要件が緩い場合のみ現実的。エンタープライズ系では基本的に通らない選択肢。
案 2: CSP に nonce / hash を追加する
‘unsafe-inline’ を許可せずに、特定のスクリプトだけをピンポイントで許可する高度な方法。サイト側で動的に nonce(一度限りの暗号値)を発行し、 CSP と inline script の両方に同じ値を埋め込みます。
メリット
- ‘unsafe-inline’ を許可せずに済む(セキュリティを保てる)
- 既存のカスタム HTML タグの内容を変えずに対応可能
デメリット
- サイト側に動的な仕組みが必要(リクエストごとに nonce を生成して埋め込む実装)
- GTM のような第三者ツールが注入する <script> に後付けで nonce を付与するのは現実的に難しい
- 大手 SaaS の管理画面ではそもそも CSP を編集できないことが多い
現実性
自社で完全にコントロールできるサイトかつ、サイト側エンジニアが nonce 配信を実装可能なケースに限られます。 GTM との相性は良くない方式。
案 3: カスタム HTML を別のタグタイプに置き換える
GTM のカスタムテンプレートやコミュニティテンプレートに移行する案。これらは ‘unsafe-eval’ で動くため、 ‘unsafe-inline’ が禁止されていても通過します。
使える場面
- 外部スクリプトを読み込むだけ のタグ → カスタムテンプレートの injectScript API で実装可能
- dataLayer に push するだけ のタグ → dataLayerPush API で対応可能
- Cookie の読み書き → getCookieValues / setCookie API
- ピクセル計測ビーコンの送信 → sendPixel API
使えない場面
- DOM イベントを監視する 処理(クリック追跡、フォーム監視、検索行為の捕捉など)
- DOM 要素を読み取る 処理(document.querySelector 系)
- DOM を書き換える 処理
これは GTM テンプレートの仕様上の意図的な制限です。サンドボックス化された JavaScript で動くため、 DOM 操作系の API はそもそも提供されていません。「自由欄」だからこそ DOM 操作ができてしまうカスタム HTML タグとは、ここが決定的に違います。
現実性
シンプルな計測タグなら案 3 で大半が解決できますが、 DOM 監視が必要なロジックは別の手段が必要。
案 4: 計測ロジックをサイト側に移植する
最後の選択肢にして、最も筋が良い解決策。サイト側のソースコードで直接 dataLayer.push を呼び、 GTM 側はカスタムイベントトリガーでそれを受けて GA4 タグを発火させる、という構成に変えます。
具体的にはこんな流れ。
[サイト側のコード]
ユーザーがサイト内検索を実行
↓
window.dataLayer.push({ event: ‘site_search’, search_term: ‘AI’ })

[GTM 側]
カスタムイベントトリガー「site_search」が発火
↓
GA4 イベントタグが起動して GA4 にイベント送信
メリット
- CSP の制約を完全に回避できる(サイト側コードは CSP の許可対象内で動くため)
- 計測ロジックの品質が上がる場合が多い(DOM スクレイピングを卒業して、 API レスポンスから確実なデータを取れる、など)
- メンテナンス性も向上(DOM 構造の変更に強くなる)
デメリット
- サイト側の開発リソースが必要
- リリースサイクルが GTM 単独より遅くなる
- 開発担当者との連携が必須
現実性
中長期的にはこれが本命。 SharePoint Online であれば SPFx(SharePoint Framework)で実装、 WordPress なら functions.php やテーマカスタマイズ、 React や Vue のサイトなら該当コンポーネントの中、というように、サイトの構造に応じて実装場所を選びます。
「計測タグを GTM の中で完結させる」発想から、「計測のためのデータ供給はサイト側、計測の配信制御は GTM 側」という役割分担の発想にシフトすることが、結果として CSP との共存にもつながります。
案の選び方の指針
整理するとこんな目安になります。
| 状況 | 推奨案 |
| 自社サイトで管理権限あり、急ぎたい | 案 1(慎重に判断) |
| タグの中身が外部スクリプト読み込みや dataLayer push だけ | 案 3 |
| DOM 監視や複雑な処理が必要 | 案 4 |
| 中長期で計測品質も上げたい | 案 4 |
| 大手 SaaS 上で計測している | 案 3 か 案 4(案 1 は通らない) |

計測担当者として持っておきたい視点
CSP はこれからもっと厳しくなる
CSP の採用率は毎年ステディに上昇しており、 2025 年の 22% は通過点に過ぎません。エンタープライズ SaaS の標準装備化、ブラウザのデフォルト挙動の厳格化、各種規制の強化。今後数年で「CSP との共存」は計測担当者の標準スキルになっていくはず。
カスタム HTML タグへの依存を下げる発想
GTM のカスタム HTML タグは「自由欄」だからこそ便利で、何でも書きたくなる誘惑があります。ただし、その自由は CSP やセキュリティの観点では脆弱性そのもの。新規にタグを設計するときは、
- 標準タグで対応できないか
- カスタムテンプレートで対応できないか
- それでもダメならサイト側に処理を移植できないか
という優先順位で考えると、将来 CSP に直面しても慌てずに済みます。
開発担当者との会話で使える共通言語
非エンジニアの計測担当者がエンジニアと会話するときに、知っていると話が早いキーワードを最後にまとめておきます。
- 「インラインスクリプトの注入が CSP の ‘unsafe-inline’ 非許可で動かない」
- 「’unsafe-inline’ を許可せずに済む方法を探したい」
- 「dataLayer.push をサイト側で直接実行してもらえないか」
- 「カスタムイベントトリガーで受けるので、 push の中身だけ実装してほしい」
これらが言えるだけで、エンジニア側との認識合わせが圧倒的にスムーズになります。「動かない」という症状の共有から、「こういう設計で解決したい」という提案ベースの会話に切り替えられる。これが、計測担当者が CSP を学ぶ実利的な価値だと思います。
CSP は計測担当者にとって制約として現れることもありますが、本質的にはサイト利用者を守る防御層。それと共存しながら計測を成立させる発想こそ、これからの GTM 使いに求められる視点。 「動かないタグ」と「動くサイト」の間で板挟みになったときに、原因を見抜き、選択肢を提示し、関係者と建設的な会話ができる存在になれるか。 CSP の理解は、そのための足がかりになります。
参考リンク
統計・調査データ
- Web Almanac 2025 – Security HTTP Archive が毎年公開している Web の実態調査。本記事の CSP 採用率(2025 年で 21.9%)の出典
- Web Almanac 2024 – Security 前年版。 2021 年からの推移データも掲載
CSP の仕様・解説
- Content Security Policy Level 3 (W3C Working Draft) W3C による現行の CSP 仕様書
- Content Security Policy (CSP) – MDN Web Docs Mozilla による包括的な日本語ドキュメント。ディレクティブ一覧や具体例も豊富
- Content-Security-Policy ヘッダー – MDN Web Docs 各ディレクティブの詳細なリファレンス
CSP の確認・診断ツール
- Mozilla Observatory URL を入れるだけで CSP を含む各種セキュリティヘッダーを診断
- CSP Evaluator (Google) CSP の各ディレクティブごとに脆弱性を指摘してくれる Google 製ツール
- securityheaders.com 各種セキュリティヘッダーを A 〜 F でスコアリング
GTM 関連の公式ドキュメント
- カスタムタグ – タグ マネージャー ヘルプ Google 公式のカスタム HTML タグ解説
- カスタム テンプレート – Tag Manager デベロッパー ガイド カスタムテンプレートで利用可能な API 一覧など

コメント