メインコンテンツまでスキップ

External Resource Integrity

概要​

本文書で定義される External Resource Integrity は画像や動画などの外部リソースファイルの完全性を保証するための Content Attestation (CA) のプロパティです。 URL が参照するリソースの完全性を保証できる一方で、扱える URL はユーザーエージェントに依らず同じバイト列をレスポンスとして返却するものに限られます。

注記

この External Resource Integrity について実証実験の参加企業の方々からフィードバックをいただく予定です。また関連する仕様のアップデートの状況を見ながらよりよい方法を将来追加する可能性があります。

参考: 画像加工を伴う CDN 利用時の検証可能化方法の検討

範囲​

  • 動画ファイルについては Adaptive Bitrate Streaming で配信される動画は扱いません。単一の動画ファイルとして配信される動画のみ扱います。
  • background-image CSS プロパティや content CSS プロパティといった CSS で取得表示されるリソースは本文書の範囲外です。
  • コンテンツネゴシエーションによる動的なリソースは本文書の範囲外です。

用語​

本文書に説明のない用語については、用語を参照してください。

  • Content Attestation (CA)

External Resource Integrity の形式​

JSON オブジェクトでなければなりません。 External Resource Integrity の具体例を次に示します。

{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#hero-image",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
}

以下のプロパティが定義されます:

NameTypeDescription
typestringREQUIRED. 必ず ExternalResourceTargetIntegrity でなければなりません (MUST)。
integritystringREQUIRED. sriString データ型 でなければなりません (MUST)。使用可能なハッシュ関数についてはハッシュアルゴリズムに準拠してください (MUST)。具体例: sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U=
cssSelectorstringOPTIONAL. 必ず CSS セレクター (Selectors Level 3) でなければなりません (MUST)。このプロパティがある場合、対象となる HTML 要素の特定に integrity 属性ではなく CSS セレクターを使用します。具体例: #hero-image
注記

CA 発行者は、ページの動的な変化によらず cssSelector がマッチする要素が変わらないように cssSelector を指定してください (RECOMMENDED)。たとえば、cssSelector に img などのタグ名だけを指定するのではなく、 #hero-image, img.rareClassName のようにより詳細な CSS セレクターを指定してください。対象要素を安定的に一意に特定するような CSS セレクターがないときには、ページを更新して、対象要素に id 属性を指定するなどして特定しやすいようなページ設計をしてください (RECOMMENDED)。

設定方法​

検証対象の HTML 要素は、次のいずれかの方法で特定できるようにします。

  • cssSelector プロパティを使用する場合: 検証対象リソースを参照する HTML 要素リストにマッチする CSS セレクターを cssSelector プロパティに指定します。
  • cssSelector プロパティを使用しない場合: integrity プロパティと同じ値を HTML 要素の integrity 属性に指定します。

例​

cssSelector プロパティで要素を特定する場合​

source 要素と img 要素を cssSelector プロパティで参照する場合の具体例を次に示します。

External Resource Integrity:

[
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#hero-image-source",
"integrity": "sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
},
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#hero-image",
"integrity": "sha256-t7WZSGxDdqGvGg/FLw6wk9KFQy5StT1MquCf/htwjBo= sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
}
]

このとき Web ページの HTML の source 要素と img 要素に、次のように CSS セレクターがマッチするようにします。

<picture>
<source
id="hero-image-source"
srcset="image.jpg"
media="(min-width: 400px)"
/>
<img id="hero-image" src="https://cdn.example.com/image.jpg" />
</picture>

video 要素を cssSelector プロパティで参照する場合の具体例を次に示します。

External Resource Integrity:

[
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#product-video",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w= sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
},
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#product-video-mp4",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
},
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#product-video-webm",
"integrity": "sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
}
]

このとき Web ページの HTML の video 要素と source 要素に、次のように CSS セレクターがマッチするようにします。

<video id="product-video" poster="https://cdn.example.com/poster.jpg">
<source
id="product-video-mp4"
src="https://cdn.example.com/video.mp4"
type="video/mp4"
/>
<source
id="product-video-webm"
src="https://cdn.example.com/video.webm"
type="video/webm"
/>
</video>

同じリソースを参照する複数の要素をひとつの External Resource Integrity で参照する場合の具体例を次に示します。

External Resource Integrity:

{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": ".site-logo",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
}

このとき Web ページの HTML の img 要素に、次のように CSS セレクターがマッチするようにします。.site-logo は 2 つの img 要素にマッチするため、そのどちらも integrity プロパティと一致しなければなりません (MUST)。

<header>
<img class="site-logo" src="https://cdn.example.com/logo.png" />
</header>
<footer>
<img class="site-logo" src="https://cdn.example.com/logo.png" />
</footer>

integrity 属性で要素を特定する場合​

source 要素と img 要素を External Resource Integrity から参照する場合の具体例を次に示します。

External Resource Integrity:

[
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
},
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-t7WZSGxDdqGvGg/FLw6wk9KFQy5StT1MquCf/htwjBo= sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
}
]

このとき Web ページの HTML の source 要素と img 要素に次のように integrity 属性を付与します。

<picture>
<source
srcset="image.jpg"
media="(min-width: 400px)"
integrity="sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
/>
<img
src="https://cdn.example.com/image.jpg"
integrity="sha256-t7WZSGxDdqGvGg/FLw6wk9KFQy5StT1MquCf/htwjBo= sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U="
/>
</picture>

video 要素を External Resource Integrity から参照する場合の具体例を次に示します。

External Resource Integrity:

[
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w= sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
},
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
}
]

このとき Web ページの HTML の source 要素と video 要素に次のように integrity 属性を付与します。

<video
integrity="sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w= sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
poster="https://cdn.example.com/poster.jpg"
>
<source
src="https://cdn.example.com/video.mp4"
integrity="sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
type="video/mp4"
/>
<source
src="https://cdn.example.com/video.webm"
integrity="sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
type="video/webm"
/>
</video>

注意事項​

注記

video 要素を参照する場合、src 属性に指定された外部リソースが検証され、poster 属性に指定された外部リソースは検証されません。poster 属性に指定された外部リソースを検証可能にするための仕様は検討中です。

注記

a 要素の href 属性で指定された外部リソースを検証可能にするための仕様は検討中です。現在の検証プロセスでは src 属性または currentSrc プロパティを使用したリソース取得のみが定義されています。詳しくは GitHub Issue #127 をご確認ください。

実装上の注意点

SRI セクション 5.3 にあるように、攻撃者が既知あるいは事前に計算したハッシュ値により、同一オリジンポリシーに違反してクロスオリジンリソースの内容を推測することを防ぐために、SRI 検証結果をクロスオリジンリソースの読み込み可否に使用する場合には、事前にCORS プロトコルを使用してクロスオリジンリソースがリクエスト元と明示的に共有されていることを確認してください。

検証プロセス​

  1. External Resource Integrity に対応する HTML 要素を検索します。
    • cssSelector プロパティがある場合、cssSelector プロパティの CSS セレクターで指定した要素を検索します。対象の要素は、そのページの document のルート要素 (例えば、 HTML 文書の場合は <html> 要素) から、querySelectorAll() メソッドを使用して検索します。
      • cssSelector プロパティの構文エラーがある場合、検証失敗として扱うことがあります。(例: DOMException SyntaxError)
    • cssSelector プロパティがない場合、integrity プロパティと同じ値を integrity 属性に含む要素を検索します。
    • 要素が1つも見つからない場合、検証失敗として扱うことがあります。
  2. 手順1に該当したすべての要素に対応するリソースを取得します。
  3. 手順2で取得したそれぞれのリソースと integrity プロパティを SRI セクション 3.3.5 に規定されている方法で検証します。
    • サポートしていないハッシュアルゴリズムの場合、検証失敗として扱うことがあります。

要素位置特定方法​

cssSelector プロパティの有無に応じて次のように要素を特定します。

  • cssSelector プロパティがある場合: cssSelector プロパティの CSS セレクターで指定した要素を検索します。
  • cssSelector プロパティがない場合: integrity プロパティと同じ値を HTML 要素の integrity 属性に対し完全一致で検索します。
備考

cssSelector プロパティがなく次の場合には、integrity プロパティと HTML 要素の integrity 属性値の両者が同じ値になるように注意する必要があります。

  • integrity プロパティの値が 2 件以上の SRI ハッシュである
  • HTML 要素の integrity 属性値に読みやすさのために空白文字または改行文字を使用している

参考文献​