Subresource Integrity - Web security 编辑
Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.
Note: For subresource-integrity verification of a resource served from an origin other than the document in which it’s embedded, browsers additionally check the resource using Cross-Origin Resource Sharing (CORS), to ensure the origin serving the resource allows it to be shared with the requesting origin.
How Subresource Integrity helps
Using Content Delivery Networks (CDNs) to host files such as scripts and stylesheets that are shared among multiple sites can improve site performance and conserve bandwidth. However, using CDNs also comes with a risk, in that if an attacker gains control of a CDN, the attacker can inject arbitrary malicious content into files on the CDN (or replace the files completely) and thus can also potentially attack all sites that fetch files from that CDN.
Subresource Integrity enables you to mitigate some risks of attacks such as this, by ensuring that the files your web application or web document fetches (from a CDN or anywhere) have been delivered without a third-party having injected any additional content into those files — and without any other changes of any kind at all having been made to those files.
Using Subresource Integrity
You use the Subresource Integrity feature by specifying a base64-encoded cryptographic hash of a resource (file) you’re telling the browser to fetch, in the value of the integrity
attribute of any <script>
or <link>
element.
An integrity
value begins with at least one string, with each string including a prefix indicating a particular hash algorithm (currently the allowed prefixes are sha256
, sha384
, and sha512
), followed by a dash, and ending with the actual base64-encoded hash.
Note: An integrity value may contain multiple hashes separated by whitespace. A resource will be loaded if it matches one of those hashes.
Example integrity
string with base64-encoded sha384 hash:
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
So oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
is the "hash" part, and the prefix sha384
indicates that it's a sha384 hash.
Note: An integrity
value's "hash" part is, strictly speaking, a cryptographic digest formed by applying a particular hash function to some input (for example, a script or stylesheet file). But it’s common to use the shorthand "hash" to mean cryptographic digest, so that's what's used in this article.
Tools for generating SRI hashes
You can generate SRI hashes from the command-line with openssl using a command invocation such as this:
cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A
or with shasum using a command invocation such as this:
shasum -b -a 384 FILENAME.js | awk '{ print $1 }' | xxd -r -p | base64
Notes:
- The pipe-through-
xxd
step takes the hexadecimal output fromshasum
and converts it to binary. - The pipe-through-
awk
step is necessary becauseshasum
will pass the hashed filename in its output toxxd
. That can have disastrous consequences if the filename happens to have valid hex characters in it — becausexxd
will also decode that and pass it tobase64
.
Additionally, the SRI Hash Generator at https://www.srihash.org/ is an online tool you can use to generate SRI hashes.
Cross-Origin Resource Sharing and Subresource Integrity
For subresource-integrity verification of a resource served from an origin other than the document in which it's embedded, browsers additionally check the resource using Cross-Origin Resource Sharing (CORS), to ensure the origin serving the resource allows it to be shared with the requesting origin. Therefore, the resource must be served with an Access-Control-Allow-Origin
header that allows the resource to be shared with the requesting origin; for example:
Access-Control-Allow-Origin: *
Examples
In the following examples, assume that oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
is already known to be the expected SHA-384 hash (digest) of a particular script example-framework.js
, and there’s a copy of the script hosted at https://example.com/example-framework.js
.
Subresource Integrity with the <script> element
You can use the following <script>
element to tell a browser that before executing the https://example.com/example-framework.js
script, the browser must first compare the script to the expected hash, and verify that there's a match.
<script src="https://example.com/example-framework.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
crossorigin="anonymous"></script>
Note: For more details on the purpose of the crossorigin
attribute, see CORS settings attributes.
How browsers handle Subresource Integrity
Browsers handle SRI by doing the following:
When a browser encounters a
<script>
or<link>
element with anintegrity
attribute, before executing the script or before applying any stylesheet specified by the<link>
element, the browser must first compare the script or stylesheet to the expected hash given in theintegrity
value.Note: For subresource-integrity verification of a resource served from an origin other than the document in which it’s embedded, browsers additionally check the resource using Cross-Origin Resource Sharing (CORS), to ensure the origin serving the resource allows it to be shared with the requesting origin.
- If the script or stylesheet doesn’t match its associated
integrity
value, the browser must refuse to execute the script or apply the stylesheet, and must instead return a network error indicating that fetching of that script or stylesheet failed.
Specifications
Specification | Status | Comment |
---|---|---|
Subresource Integrity | Recommendation | |
Fetch | Living Standard |
Browser compatibility
<script integrity>
BCD tables only load in the browser
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
See also
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论