コンテンツセキュリティポリシー(CSP)

最終更新日:

コンテンツセキュリティポリシー(CSP)は、クロスサイトスクリプティング(XSS)やデータインジェクション攻撃などの、特定の種類の攻撃を検知して軽減するための追加セキュリティレイヤーです。CSPで問題が発生している場合は、Pendoが完全に機能するように調整する必要がある場合があります。

この記事では、Pendoが完全に機能するために最低限必要なディレクティブの概要と、厳密なCSPを持つアプリケーションのための互換性ガイドコンテンツの例を紹介します。

Feedbackをご利用の方は、Feedbackのコンテンツに関するセキュリティポリシーをご覧ください。

ガイド配信設定

厳密なCSPを使用するアプリケーションでは、[ガイド配信設定(Guide Delivery Settings)]がXHRに設定されていることを確認する必要があります。

ガイド配信設定にはアクセスする方法は、以下のとおりです。

  1. [設定(Settings)]>[サブスクリプション設定(Subscription Settings)]に移動します。

  2. [アプリケーション(Applications)]タブを開きます。

  3. [アプリケーション]リストから該当するアプリを見つけて開きます。

  4. [エージェント設定(Agent Settings)]タブを開きます。

  5. [本番設定を管理(Manage Production Settings)]を選択します。

  6. XHRのラジオボタンが選択されていることを確認します。

guideDisplay.png

CSP(CNAMEなし)

以下のコードブロック例におけるディレクティブとエントリの説明については、ディレクティブとエントリの用語集を参照してください。

注:以下のfoo.example.comの部分はすべて、アプリケーションのホスト名に置き換えてください。SUB_IDはお客様のサブスクリプションIDに置き換えてください。サブスクリプションIDは、PendoにログインしているときにページのURLに表示されます。フォーマットはhttps://app.pendo.io/s/[SUB_ID]/です。/s/の直後にサブスクリプションIDが表示されますが、Pendo内を移動する際にURLパスの最後に表示されるガイドやレポートの一意のIDを誤って取得しないようにしてください。

必要に応じて、ホスト名の前にhttps://を加えてください。

最低限必要なCSPディレクティブ(EU以外の米国/各国のお客様)

デザイナーを含めた全ての機能で有効です。

script-src foo.example.com 'unsafe-inline' 'unsafe-eval' app.pendo.io pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
style-src foo.example.com 'unsafe-inline' app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
connect-src app.pendo.io data.pendo.iopendo-static-SUB_ID.storage.googleapis.com;
frame-ancestors app.pendo.io;
frame-src app.pendo.io; child-src app.pendo.io;
完全なエージェント機能と本番環境でのガイドの表示:
(デザイナーおよびインラインのガイドスタイル、もしくはスクリプトは含まれません)。
script-src foo.example.com pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
style-src foo.example.com app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
connect-src app.pendo.io data.pendo.io pendo-static-SUB_ID.storage.googleapis.com;frame-ancestors app.pendo.io;
ステージングにおけるガイド表示:
script-src foo.example.com app.pendo.io pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
style-src foo.example.com app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io;
connect-src app.pendo.io data.pendo.io pendo-static-SUB_ID.storage.googleapis.com;frame-ancestors app.pendo.io;

最低限必要なCSPディレクティブ(EUのお客様)

デザイナーを含めた全ての機能で有効です。

script-src foo.example.com 'unsafe-inline' 'unsafe-eval' app.eu.pendo.io pendo-eu-static.storage.googleapis.com cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
style-src foo.example.com 'unsafe-inline' app.eu.pendo.io cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;
img-src foo.example.com cdn.eu.pendo.io app.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
connect-src app.eu.pendo.io data.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;
frame-ancestors app.eu.pendo.io;
frame-src app.eu.pendo.io; child-src app.eu.pendo.io;
完全なエージェント機能と本番環境でのガイドの表示:
(デザイナーおよびインラインのガイドスタイル、もしくはスクリプトは含まれません)。
script-src foo.example.com pendo-eu-static.storage.googleapis.com cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
style-src foo.example.com app.eu.pendo.io cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;
img-src foo.example.com cdn.eu.pendo.io app.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
connect-src app.eu.pendo.io data.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;frame-ancestors app.eu.pendo.io;

ステージングにおけるガイド表示:

script-src foo.example.com app.eu.pendo.io pendo-eu-static.storage.googleapis.com cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
style-src foo.example.com app.eu.pendo.io cdn.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;
img-src foo.example.com cdn.eu.pendo.io app.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com data.eu.pendo.io;
connect-src app.eu.pendo.io data.eu.pendo.io pendo-eu-static-SUB-ID.storage.googleapis.com;frame-ancestors app.eu.pendo.io;

CNAMEがあるCSP

以下のコードブロック例におけるディレクティブとエントリの説明については、ディレクティブとエントリの用語集を参照してください。これらの一部は、CNAMEでCSPを使用すると置き換えられます。詳細については、CNAMEを使用する場合のディレクティブとエントリを参照してください。

CNAMEがあるCSPを使用している場合、ホスト名の変更時にCSPがPendoサービスを中断することなくCNAMEを適切に設定するには、いくつかの手順を経る必要があります。PendoのサポートチームとCNAMEを設定するときに、移行コードを使用するようにCSPディレクティブを更新します。CNAMEの設定が完了した後、CNAMEのみのコードを使用して、CNAMEを使用するPendoリソースのみを許可します。

注:以下のfoo.example.comの部分(content.data.の後の部分)をすべてCNAME用に選択したサブドメインに置き換えてください。

CSPディレクティブのCNAMEへの移行

デザイナーを含めた全ての機能で有効です。
script-src foo.example.com 'unsafe-inline' 'unsafe-eval' app.pendo.io pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
style-src foo.example.com 'unsafe-inline' app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
connect-src app.pendo.io data.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
frame-ancestors app.pendo.io data.pendo.example.com;
frame-src app.pendo.io data.pendo.example.com;
child-src app.pendo.io data.pendo.example.com;frame-src https://app.pendo.io;script-src https://app.pendo.io
リプレイの場合は、CSP構成に以下を追加します。
worker-src blob:
完全なエージェント機能と本番環境でのガイドの表示:
script-src foo.example.com pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
style-src foo.example.com app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
connect-src app.pendo.io data.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
ステージングにおけるガイド表示:
script-src foo.example.com app.pendo.io pendo-io-static.storage.googleapis.com cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
style-src foo.example.com app.pendo.io cdn.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
img-src foo.example.com cdn.pendo.io app.pendo.io pendo-static-SUB_ID.storage.googleapis.com data.pendo.io content.pendo.example.com data.pendo.example.com;
connect-src app.pendo.io data.pendo.io pendo-static-SUB_ID.storage.googleapis.com content.pendo.example.com data.pendo.example.com;
frame-ancestors app.pendo.io data.pendo.example.com;

CNAMEのみを使用するCSPディレクティブ

デザイナーを含めた全ての機能で有効です。
script-src foo.example.com 'unsafe-inline' 'unsafe-eval' content.pendo.example.com data.pendo.example.com app.pendo.io;
style-src foo.example.com 'unsafe-inline' content.pendo.example.com data.pendo.example.com;
img-src foo.example.com content.pendo.example.com data.pendo.example.com app.pendo.io;
connect-src content.pendo.example.com data.pendo.example.com;
frame-ancestors app.pendo.io;
frame-src app.pendo.io;
完全なエージェント機能と本番環境でのガイドの表示:
script-src foo.example.com content.pendo.example.com data.pendo.example.com;
style-src foo.example.com content.pendo.example.com data.pendo.example.com;
img-src foo.example.com content.pendo.example.com data.pendo.example.com;
connect-src content.pendo.example.com data.pendo.example.com;
ステージングにおけるガイド表示:
script-src foo.example.com content.pendo.example.com data.pendo.example.com;
style-src foo.example.com content.pendo.example.com data.pendo.example.com;
img-src foo.example.com content.pendo.example.com data.pendo.example.com;
connect-src content.pendo.example.com data.pendo.example.com;

対応ガイドコンテンツ

Pendoは厳密なCSPディレクティブに対応していますが、ガイドコンテンツがお客様のCSP制限に対応しているかどうかは、お客様の責任でご確認ください。

style-srcおよびscript-srcディレクティブ内にunsafe-inlineが存在しない場合、ガイドのHTMLタブ内のインラインCSSおよびJavaScriptは正しく機能しません。予期しないガイドの表示を防ぐには、すべてのインラインスタイルとスクリプトをガイドコードブロックまたはテンプレートのCSSタブとJSタブに移動する必要があります。

最小限のCSPディレクティブ(インラインディレクティブなし)を適切に設定すれば、Pendoデザイナーでフィーチャーの表示やタグ付けができるようになります。X-Frame-Optionsプラグインにより、厳密なCSPを使用したガイド編集モードでデザイナーを使用できるようになります。デザイナーの外部で、X-Frame-Optionsプラグインをオフにしてガイドコンテンツをテストすることが重要です。

厳密なCSP対応コンテンツの例

基本的なコンセプトは、「unsafe-inline」のスタイル設定とJavaScriptをすべて削除することです。

たとえば、このHTMLボタン内のすべてのインラインスタイル設定とJavaScriptは次のようになります:

<button class="_pendo-guide-next_" style="color:blue;" onclick="pendo.onGuideAdvanced()">Next</button>

これで、ガイドのHTML、CSS、JSのそれぞれのタブに分散して表示されます。以下の例は、ガイドコンテンツの要素を分解する方法を示しています。お客様やお客様のチームの開発者は、別の、あるいはもっと良いアプローチを取っているかもしれません:

HTML

<button class="_pendo-guide-next_ blue-button">Next</button>

CSS

.bluebutton { color: blue; }

JavaScript

(function wireGuideAdvanceButton (step) { step && step.attachEvent(step.guideElement[0],'click', function (e) { var advanceButton = pendo.dom(e.target|| e.srcElement).closest('._pendo-guide-next_'); if (advanceButton.length){ pendo.onGuideAdvanced(); } }); })(step,guide);

ディレクティブとエントリの用語集

ディレクティブ:script-src

これらのエントリ(ホスト)により、Pendoのスクリプトをダウンロードして実行できます。

ホスト 説明
cdn.pendo.io

インストールスクリプト(「snippet」)で参照されるPendoエージェントの場所。これは、デフォルトでPendoエージェントがダウンロードされる場所です。

pendo-io-static.storage.googleapis.com

ステージングドメイン用にダウンロードされたPendoエージェントの場所。

pendo-static-{{ SUB_ID }}.storage.googleapis.com

すべてのガイドコンテンツの場所。

data.pendo.io

訪問者が利用できるガイドのリストをダウンロードするために使用されます。これは、JSONP配信メソッドにのみ必要です。

app.pendo.io

デザイナーを使用する場合にのみ必要です。

'unsafe-inline'

デザイナーでカスタムコードブロックまたはクラシックガイドを使用する場合にのみ必要です。

'unsafe-eval'

デザイナーでカスタムコードブロックまたはクラシックガイドを使用する場合に必要です。

 

ディレクティブ:style-src

これらのエントリ(ホスト)により、貴社のサイトでPendoのスタイルを使用できるようになります。

ホスト 説明
pendo-io-static.storage.googleapis.com

クラシックガイドが有効になっている場合にのみ必要です。このURLからデフォルトのガイドCSSが読み込まれます。

pendo-static-{{ SUB_ID }}.storage.googleapis.com

ガイドスタイルとグローバルCSS。

'unsafe-inline'

ガイドの擬似スタイル(ホバー、リソースセンターのキャレット、数値スケール)およびデザイナー起動時のスタイルに使用されます。

app.pendo.io

デザイナーを使用する場合にのみ必要です。

 

ディレクティブ:img-src

これらのエントリにより、Pendoがホストする画像をサイトに表示できます。

ホスト 説明
cdn.pendo.io

デフォルトのクラシックガイドのバッジに使用されます。

data.pendo.io

イベントは、画像srcを使用してこのURLに送信されます。

pendo-static-{{ SUB_ID }}.storage.googleapis.com

ガイド画像はこちらのURLからダウンロードされます。

app.pendo.io

デザイナーを使用する場合にのみ必要です。

data:

デフォルトのバッジ画像。バッジにカスタム画像を使用する場合、これは必要ありません。

 

ディレクティブ:connect-src

これらのエントリにより、ページ上のスクリプトがPendoと通信できるようになります。

ホスト 説明
data.pendo.io イベント通信とPendo Replayに必要です。
pendo-static-{{ SUB_ID }}.storage.googleapis.com

ここにガイド構造ファイルを読み込みます。

app.pendo.io

デザイナーを使用する場合にのみ必要です。

 

ディレクティブ:frame-ancestors

このエントリは、Pendoがサイトのページを<frame>内に読み込むようにするためのものです。クラシックデザイナーを使用している場合のみ必要です。

ホスト 説明
app.pendo.io

クラシックデザイナーがアプリケーションを読み込むPendoホスト。

 

ディレクティブ:rame-src

このエントリにより、Pendoはサイトの<frame>内にデザイナーを読み込むことができます。

ホスト 説明
app.pendo.io

ビジュアルデザインスタジオ(Visual Design Studio)は、このURLから読み込まれます。ガイドの設計にのみ必要です。

 

ディレクティブ:worker-src

このエントリにより、Pendoエージェントはworkerスレッドを開始して、アプリケーションへのパフォーマンスの影響を最小限に抑えることができます。

ホスト 説明
blob:

Pendoエージェントは、ウェブworkerを起動して、Pendoリプレイのセッションキャプチャデータを圧縮して送信します。これは、セッションキャプチャ全体のパフォーマンスを向上させるために行われます。

CNAMEを使用する場合のディレクティブとエントリ

CNAMEを使用する場合、上記のディレクティブとエントリの用語集の下に記載されているいくつかのエントリが置き換えられます。

ダウンタイムを防ぐために、CNAMEを設定するプロセスで、上記のURLと、その新しいコンテンツとデータホストの両方を含めるようにします。それを以下に示します。

ホスト 説明
cdn.pendo.io

content.pendo.example.comのように、どこでもコンテンツホストに置き換えられます。

pendo-io-static.storage.googleapis.com

content.pendo.example.comのように、どこでもコンテンツホストに置き換えられます。

pendo-static-{{ SUB_ID }}.storage.googleapis.com

content.pendo.example.comのように、どこでもコンテンツホストに置き換えられます。

data.pendo.io

data.pendo.example.comのように、どこでもデータホストに置き換えられます。

app.pendo.io

デザイナーを使用するには引き続き必要です。

'unsafe-inline'

デザイナーでカスタムコードブロックまたはクラシックガイドを使用する場合は引き続き必要です。

'unsafe-eval'

デザイナーでカスタムコードブロックまたはクラシックガイドを使用する場合は引き続き必要です。

data:

前述のルールに従う場合は、引き続き必要です。

 

Trusted Types

Trusted Typesは、現在Chromiumベースのブラウザでのみサポートされている実験的なテクノロジーです。アプリケーションで、Trusted Typesによって提供される追加のクロスサイトスクリプティング(XSS)の保護が必要な場合は、次のディレクティブをCSPヘッダーに追加します:trusted-types pendo;。Trusted Typesのサポートには、エージェントのバージョン2.184.0以降が必要です。

よくある質問

Visual Design StudioとClassic Designerではディレクティブが違いますか?

はい。Visual Design Studioではframe-srcが使用され、Classic Designerではframe-ancestorsが使用されます。サブスクリプションでClassic Designerを使用してVisual Design Studioリリース以前に作成されたガイドを管理しない場合は、frame-ancestorsディレクティブは必要ありません。すべてのアプリケーションで、Visual Design Studioのコンテンツを許可する必要があります。これはページやフィーチャーのタグ付けや、最新のフィーチャーを使ったガイドの構築が可能な唯一のツールです。

unsafe-inlineおよびunsafe-evalディレクティブは本当に必要でしょうか?

はい。unsafe-evalディレクティブは、クラシックデザイナーの全機能を利用するために必要であり、 unsafe-inlineディレクティブは、公開されているガイドやビジュアルデザインスタジオの全機能を利用するために必要です。

その他のリソース

この記事は役に立ちましたか?
9人中6人がこの記事が役に立ったと言っています