コンテンツセキュリティポリシー(Content Security Policy)はアクセス、利用できるリソースを限定することで、XSS(クロスサイトスクリプティング)やデータインジェクションなど、クライアントサイドにおける脅威の影響を軽減できる仕組みです。

この記事ではコンテンツセキュリティポリシーの基本と、その書き方を解説します。

Monacaアプリにおけるコンテンツセキュリティポリシー

コンテンツセキュリティポリシーは最初に読み込まれるファイルに記述します。つまり www/index.html になります。このファイルを開くと、次のような記述があるのが分かるはずです。これがコンテンツセキュリティポリシーです。

<meta http-equiv="Content-Security-Policy"
      content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:;worker-src * blob:"
>

コンテンツセキュリティポリシーの内容

指定できるリソースの種類

コンテンツセキュリティポリシーは利用するリソースの種類と、それを利用できるデータ元という形で記述します。つまり上記の例で言えば、リソースの種類は次の2つになります。

  • default-src
  • worker-src

他に以下のようなリソースがあります。default-srcが指定されていることで、すべてのリソースに対してdefault-srcの条件が適用された上で、各リソースの条件に変更を加えられます。

また、worker-srcは、Worker,SharedWorker, ServiceWorkerスクリプトの有効なソースを指定します。

  • img-src
    画像
  • media-src
    音声や動画
  • script-src
    JavaScript の scriptタグ
  • child-src
    iframeやframeタグ、そしてその中で読み込まれるworker
  • connect-src
    fetchやXMLHttpRequest、WebSocketなどJavaScriptを介して読み込まれる外部リソース
  • font-src
    フォント
  • form-action
    フォーム送信
  • frame-ancestors
    frame/iframe/object/embed/applet
  • frame-src
    iframe/frame
  • manifest-src
    manifest
  • object-src
    object/embed/applet
  • script-src-attr
    HTML中のonclickなど
  • script-src-elem
    script
  • style-src
    style
  • style-src-attr
    HTML中のstyle要素
  • style-src-elem
    style

指定できるリソース

コンテンツセキュリティポリシーは次のように記述します。リソースは複数種類指定できます(スペースで区切ります)。最後に ; を書いて、次のリソースを指定します。

(指定できるリソースの種類) (リソース1) (リソース2) (リソース3);

リソースの種類によって直接書けるものと、シングルクォートで囲む必要があるものがあります。

直接書けるリソース

直接指定できるリソースは下記があります。URLは * を使ってワイルドカードにすることもできます。

  • URL

    • .example.com
      https://
      .example.com
      https://api.example.com
  • *(アスタリスク)
  • スキーム
    • http:
    • https:
    • data:
    • blob:
    • content:
    • gap:
    • mediastream:
    • filesystem:

文字列で指定するリソース

文字列で指定するリソースは次の通りです。シングルクォートで囲んでください。

  • self
    同じURLスキーム、ポート番号のみ
  • unsafe-eval
    evalの利用を許可
  • unsafe-hashes
    インラインでのイベントハンドラー記述を許可
  • unsafe-inline
    javascript: やインラインでのscriptタグの許可
  • none
    許可しない場合
  • nonce-<base64-value>
    一時的に許可されるノンスを使って、さらにセキュアに実行対象を絞り込みます
  • <hash-algorithm>-<base64-value>
    上記に似ていますが、さらにハッシュ化アルゴリズムを指定します
  • strict-dynamic
    マークアップ内のスクリプトを明示的に信用する

Monacaアプリのデフォルトコンテンツセキュリティポリシーを読み解く

では、最初に戻ってMonacaアプリに記述されているコンテンツセキュリティポリシーは、次のように記述されています。

<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:;worker-src * blob:">

まず、すべてのリソースに対して次のように設定されています。

  • *
    すべての外部コンテンツ
  • 'self'
    ローカルファイル
  • 'unsafe-inline'
    インラインでの記述
  • 'unsafe-eval'
    evalを許可
  • data:
    data:の許可
  • gap:
    iOS用(プラグイン)
  • content:
    Android用(プラグイン)

そしてWeb Workerに対しては、次のように定義しています。

  • *
    すべての外部コンテンツ
  • blob:
    blobでの適用許可

他は必要があれば、開発者自身が追加可能です。

まとめ

コンテンツセキュリティポリシーを適切に利用することで皆さんのアプリは安心、安全なものになります。特にimg-srcやscript-srcはインシデントに繋がりやすいので、慎重に設定することをお勧めします。

CSP: connect-src - HTTP | MDN