Given code like this:
import { el, mount } from 'https://unpkg.com/[email protected]/dist/redom.es.js';
is there some way to enable subresource integrity verification to ensure that the CDN asset returns the expected content?
Given code like this:
import { el, mount } from 'https://unpkg.com/[email protected]/dist/redom.es.js';
is there some way to enable subresource integrity verification to ensure that the CDN asset returns the expected content?
From an HTML document, you can use the <link rel="modulepreload">
element to perform that integrity check, which is unfortunately currently supported only in Blink browsers.
// default script
import( "https://unpkg.com/[email protected]/dist/redom.es.js" )
.then( module => console.log( 'from default script:', typeof module.List ) )
.catch( console.error );
<link rel="modulepreload"
href="https://unpkg.com/[email protected]/dist/redom.es.js"
integrity="sha384-notthecorrectsha">
<script type="module">
import { List } from "https://unpkg.com/[email protected]/dist/redom.es.js";
console.log( 'from module script:', typeof List );
</script>
The same snippet without the integrity check:
// default script
import( "https://unpkg.com/[email protected]/dist/redom.es.js" )
.then( module => console.log( 'from default script:', typeof module.List ) )
.catch( console.error );
<link rel="modulepreload"
href="https://unpkg.com/[email protected]/dist/redom.es.js">
<script type="module">
import { List } from "https://unpkg.com/[email protected]/dist/redom.es.js";
console.log( 'from module script:', typeof List );
</script>
Note that this check would also apply to "sub-modules", but not to Workers.
You have to also define the module via
<script type="module" integrity="..." src="https://unpkg.com/[email protected]/dist/redom.es.js">
What you're asking specifically requires changes to ECMAScript itself and currently there's not even a proposal for it, so I don't expect it to appear anytime soon.
However in the case of UNPKG, if you trust UNPKG and Cloudflare not to mess with the content, you're fine. Neither npm nor the package author can modify the file as long as you specify the version.
integrity
attributes. –
Medicament <script>
tag with broken integrity
and then later import
the same URL, the <script>
tag will fail to load, but the import
will initiate an additional network request and then run the code. –
Northwards With Deno supporting such imports for its dependencies (and having no out-of-the-box package manager) and Node leaving open the chance for importing non-file URLS in the future, this issue becomes even more important.
While what @fregante mentions about there not being yet a proposal remains accurate, https://github.com/WICG/import-maps/issues/174 includes discussion, including via a referenced slide presentation, of some of the questions raised in modifying the syntax (e.g., transitive dependency cache invalidation) to support SRI as well as other possible alternatives.
You can use RequireJS, and transpile your code to AMD or UMD to achieve this.
RequireJS has a hook onNodeCreated
, which gives you access to the script tag before it is added to document.
You can add the sri
attribute onto the script
tag:
onNodeCreated: function(node, config, module, path) { node.setAttribute('integrity', integrityForModule); node.setAttribute('crossorigin', 'anonymous'); }
credit: https://stackoverflow.com/a/37065379
I use Webpack (with a target of UMD) and RequireJS.
With the relevant modules put in the external
section of the webpack configuration file, so the modules are not compiled into the transpiled code.
I'm working through a practical solution and this is what I have so far. I consume external dependencies from any given specific URL (unpkg, cdn, github, etc) and use Deno to cache the content from those urls, generate a lock file with the hashes, then from that ensure the cache and lock file are used to generate a bundle, failing to generate the bundle when invalid. Reviewing the source from this as indicated and process with testing which ensures the bundle is generally what's expected. Later processing the external bundle as desired to fit any given use-case (minify, etc).
in my project:
DENO_DIR=./cache deno cache --lock=lock.json --lock-write ./deps.js
deno bundle --lock=lock.json ./deps.js ./bundle.js
deps.js simply has a list of valid es module import/export statements as with any es module and can be used directly (eg in development) instead of the bundle; Deno also supports import maps which would allow local paths, bare imports and remapping various patterns (see the docs); I expect to actually both manually review version controlled content and possibly have other testing against the bundle to ensure it's looks/works right. This basically ensures, if it works properly, everything the project has is generally trusted and can be redistributed and supported (with my own CSP headers and everything served from limited/restricted environments).
this solution and answer gleaned from: https://deno.land/manual/linking_to_external_code https://github.com/denoland/deno/issues/6491 notable: https://github.com/denoland/deno/security/advisories/GHSA-xpwj-7v8q-mcgj
Please note, SRI doesn't address the sources (whether a URL, CDN, npm, etc) prior to implementing this answer's solution, including transformations which occur along the way, whether within or between a project and delivery (eg via a CDN). Obviously reviewing incoming code and processing it appropriately is the only way to ensure what a given project then generates hashes for is what then follows as having a certain expectation of integrity.
unpkg.com
or esm.sh
my understanding is that the implementations of SRI are not complete or reliable. If you see otherwise please explain with relevant detail. Thanks. –
Niggling © 2022 - 2024 — McMap. All rights reserved.
integrity
attribute on a<script type="module">
in a browser that supports both features (i.e. Chrome 61)? – Wobbling<link rel="preload">
with an integrity attribute: github.com/w3c/webappsec-subresource-integrity/issues/26 and github.com/w3c/webappsec-subresource-integrity/issues/70 – Wobbling