External Resource Integrity
Summary
The External Resource Integrity defined in this document is a Content Attestation (CA) property for assuring the integrity of external resource files such as images, videos, etc. While it can assure the integrity of the resource referenced by a URL, it is limited to URLs that return the same byte sequence as a response regardless of the user agent.
We plan to receive feedback on this External Resource Integrity from the companies participating in the pilot experiments. We may add better methods in the future while monitoring the status of updates to related specifications.
Reference: Consideration of a method to enable verification when using CDN with image processing
Scope
- As for video files, videos delivered with Adaptive Bitrate Streaming are not supported. Only videos delivered as a single video file are supported.
- Resources that are rendered via CSS, such as the background-image CSS property or the content CSS property, are outside the scope of this document.
- Dynamic resources through content negotiation are outside the scope of this document.
Terminology
For terms not explained in this document, please see Terminology.
- Content Attestation (CA)
External Resource Integrity Format
It must be a JSON object. Below is an example of an External Resource Integrity:
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": "#hero-image",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
}
The following properties are defined:
| Name | Type | Description |
|---|---|---|
type | string | REQUIRED. It MUST be ExternalResourceTargetIntegrity. |
integrity | string | REQUIRED. It MUST be the sriString data type. For available hash functions, it MUST conform to Hash Algorithm. Example: sha256-4HLmAAYVRClrk+eCIrI1Rlf5/IKK0+wGoYjRs9vzl7U= |
cssSelector | string | OPTIONAL. It MUST be a CSS Selector (Selectors Level 3). When this property is present, the CSS selector is used instead of the integrity attribute to identify the target HTML element. Example: #hero-image |
CA issuers should specify cssSelector so that the elements that cssSelector matches will not change regardless of dynamic changes to the page (RECOMMENDED). For example, instead of specifying only a tag name such as img for cssSelector, specify a more specific CSS selector such as #hero-image or img.rareClassName. If there is no CSS selector that can stably and uniquely identify the target element, it is RECOMMENDED to update the page and design the page so that it is easier to identify, for example by specifying an id attribute for the target element.
How to set it up
Make the HTML elements to be verified identifiable by either of the following methods:
- When using the
cssSelectorproperty: Specify in thecssSelectorproperty a CSS selector that matches the list of HTML elements referencing the resource to be verified. - When not using the
cssSelectorproperty: Specify the same value as theintegrityproperty for theintegrityattribute of the HTML element.
Example
Identifying elements by the cssSelector property
Below is an example of referencing the source and img elements with the cssSelector property:
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="
}
]
In this case, make the CSS selectors match the HTML source element and img element of the web page as follows:
<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>
Below is an example of referencing a video element with the cssSelector property.
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="
}
]
In this case, make the CSS selectors match the HTML video element and source elements of the web page as follows:
<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>
Below is an example of referencing multiple elements that reference the same resource from a single External Resource Integrity.
External Resource Integrity:
{
"type": "ExternalResourceTargetIntegrity",
"cssSelector": ".site-logo",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w="
}
In this case, make the CSS selector match the HTML img elements of the web page as follows. Since .site-logo matches two img elements, both of them MUST match the integrity property.
<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>
Identifying elements by the integrity attribute
Below is an example of referencing the source and img elements from an 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="
}
]
In this case, add the integrity attribute to the HTML source element and img element of the web page as follows:
<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>
Below is an example of referencing a video element from an External Resource Integrity.
External Resource Integrity:
[
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-OYP9B9EPFBi1vs0dUqOhSbHmtP+ZSTsUv2/OjSzWK0w= sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
},
{
"type": "ExternalResourceTargetIntegrity",
"integrity": "sha256-zc3KMRPJkbv6p7sOq5Di/CNe+4XyqBBuiKjzP3A3NP0="
}
]
In this case, add the integrity attribute to the HTML source element and video element of the web page as follows:
<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>
Notes
When referencing a video element, the external resource specified in the src attribute is validated, but the external resource specified in the poster attribute is not validated. Specifications for making external resources specified in the poster attribute verifiable are under consideration.
A specification is under consideration to enable verification of external resources specified in the href attribute of the a element. The current verification process only defines resource retrieval using the src attribute or the currentSrc property. For more information, see GitHub Issue #127.
As described in SRI Section 5.3, in order to prevent an attacker from inferring the content of a cross-origin resource in violation of the Same-Origin Policy by using a known or precomputed hash, when using the SRI validation result to determine the loadability of the cross-origin resource, ensure beforehand that the cross-origin resource is explicitly shared with the request initiator using the CORS protocol.
Validation Process
- Searches for the HTML elements corresponding to the External Resource Integrity.
- If the
cssSelectorproperty is present, it searches for elements specified by the CSS selector in thecssSelectorproperty. The target elements are searched for using thequerySelectorAll()method, starting from the root element of the page'sdocument(for example, the<html>element for an HTML document).- If there is a syntax error in the
cssSelectorproperty, it may be treated as a verification failure (e.g.DOMExceptionSyntaxError).
- If there is a syntax error in the
- If the
cssSelectorproperty is absent, it searches for elements whoseintegrityattribute contains the same value as theintegrityproperty. - If no elements are found, it may be treated as a verification failure.
- If the
- Retrieves the resources corresponding to all the elements identified in step 1.
- The resources are fetched from the URL of the attribute or property corresponding to the element type.
- img element:
HTMLImageElement.currentSrcproperty - video or audio element:
HTMLMediaElement.currentSrcproperty - Other elements:
srcattribute
- img element:
- If a network error occurs, it may be treated as a verification failure (e.g.
TypeErrorFailed to fetch., etc.).
- The resources are fetched from the URL of the attribute or property corresponding to the element type.
- Validate each of the resources retrieved in step 2 and the
integrityproperty using the methods specified in SRI section 3.3.5.- If an unsupported hash algorithm is used, it may be treated as a verification failure.
How to identify element location
Elements are identified as follows, depending on whether the cssSelector property is present:
- If the
cssSelectorproperty is present: Searches for elements specified by the CSS selector in thecssSelectorproperty. - If the
cssSelectorproperty is absent: Searches for an exact match of theintegrityproperty value in theintegrityattribute of HTML elements.
If the cssSelector property is absent, care must be taken to ensure that both the integrity property and the value of the integrity attribute of the HTML element have the same value in the following cases:
- The value of the
integrityproperty consists of two or more SRI hashes - Whitespace or line break characters are used in the value of the
integrityattribute of the HTML element for readability
References
- W3C Subresource Integrity
- webappsec-subresource-integrity/signature-based-restrictions-explainer.markdown at main · w3c/webappsec-subresource-integrity
- Content Security Policy Level 3
- Apply subresource integrity to
<img>tags · Issue #113 · w3c/webappsec-subresource-integrity - integrity for downloads · Issue #68 · w3c/webappsec-subresource-integrity
- SRI: Integrity enforcement on downloads · Issue #497 · w3c/webappsec
- [SRI] Support signatures/asymm key · Issue #449 · w3c/webappsec
- Consideration: Allow integrity-check based on signature instead of actual hash · Issue #85 · w3c/webappsec-subresource-integrity