Add native support for SRI
Is your feature request related to a problem? Please describe. https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
Describe the solution you'd like Use https://github.com/JonasKruckenberg/rollup-plugin-sri by default to add tokens to the tags.
Describe alternatives you've considered Guide, option
@Exelord Hey Maciej, were you able to get that SRI plugin to work in Vite 2 at all? I’ve tried adding it to plugins (and, later to just, build.rollupOptions.plugins) but all I’m seeing is crossorigin added to one of the script tags and no integrity hashes. (I’ve tried it with and without also incuding the @rollup/plugin-html as suggested in the docs.)
Update: I’ve now tried my index.html in the rollup-plugin-sri test suite and it passes so I’m going to answer my own question here and say that there is an issue while using that plugin with Vite (or Vite + Svelte) currently.
Also, I just noticed that I’m getting a non-warning warning in the output, which might be related:
rendering chunks (2)...The emitted file "index.html" overwrites a previously emitted file of the same name.
Vite config file:
import os from 'os'
import fs from 'fs'
import path from 'path'
import { defineConfig } from 'vite'
import svelte from '@sveltejs/vite-plugin-svelte'
import sri from 'rollup-plugin-sri'
import html from '@rollup/plugin-html'
const certDirectory = path.join(os.homedir(), '.small-tech.org', 'auto-encrypt-localhost')
const cert = fs.readFileSync(path.join(certDirectory, 'localhost.pem'))
const key = fs.readFileSync(path.join(certDirectory, 'localhost-key.pem'))
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
server: {
port: 444,
https: {key, cert}
},
build: {
outDir: 'dist',
rollupOptions: {
plugins: [html(), sri()]
}
}
})
(Although, as previously mentioned, same results when not including html plugin and when including sri and/or html and sri in root plugins array instead of build.rollupOptions.plugins as shown here.)
Hi Aral. Yeah, I had similar issue. I was not able to set it up on my own, that's why I raised this issue to handle SRI as a default Vite feature as it's not quite easy to do so independently, and it's definitely a core security feature.
Very curios if somebody had achieved that, though :)
@Exelord Thanks! Looking into it further, it appears that Vite has a special hook for transforming the index HTML file: https://vitejs.dev/guide/api-plugin.html#transformindexhtml – I’m going to take a look at modifying the plugin to make use of it.
Also opened an issue there to track: https://github.com/JonasKruckenberg/rollup-plugin-sri/issues/99
Quick heads up: I’m rolling my own very simple Vite plugin. Will update once it’s ready.
Hello again, it’s out :)
https://github.com/small-tech/vite-plugin-sri
Also note that Jonas is also working on getting his more generic/configurable rollup plugin that mine was inspired by working with Vite too. You can keep an eye on the progress of that here: https://github.com/JonasKruckenberg/rollup-plugin-sri/issues/99
@aral nice! @Exelord if everything you need from Vite to create this plugin is already available, let's close this issue. Consider sending the plugin to https://github.com/vitejs/awesome-vite once it is ready so others can discover it, and also share it in the #plugins channel in https://chat.vitejs.dev
Im also proposing to make it a default in Vite :) Its a core security feature which shouldn't be optional. The whole community can benefit from it.
Is it possible generate SRI directly to manifest file? Not just change in index HTML file (which I don't use it).
@pepa-linha Created vite-plugin-manifest-sri, which might be useful for your use case.
@ElMassimo Thanks, it looks good. (I created something similar, I have to modify the manifest more, because, for example, styles that are like input for Rollup are not generated in it)
Im also proposing to make it a default in Vite :) Its a core security feature which shouldn't be optional. The whole community can benefit from it.
Just like the integrity option of VueCLI
Hello, just wanted to let the team know: the workarounds mentionned in this thread are not ideal. None of them support integrity hashes on dynamically loaded modules.
This is blocking us from migrating from CRA to vite, as webpack-subresource-integrity (used internally by CRA) supports this, and it is a really important feature for us.
I think whatever native solution is brought into vite should have parity with webpack-subresource-integrity if possible, thanks 🙏 !
"None of them support integrity hashes on dynamically loaded modules." - I may be in the process of making this general observation as well, but I am super-new to both Vite and Vue so I do think I'm still missing something in my understanding. I am adding my details to this thread in case others are observing something similar, looking for a little guidance myself, and offering to help, if I can.
Specifically, it appears to me that something (...probably the Vue plug in? Or vite itsef?) adds additional javascript content to the output .js files AFTER the transformIndexHtml has completed in the SRI plugins, even with enforce: 'post'. Since the SRI plugins compute the corresponding modules' Javascript files' hashes BEFORE this additional content is added, the hashes no longer represent the contents, and fail both SRI and CSP.
This appears to be the case empirically for both vite-plugin-sri and rollup-plugin-sri. I didn't actually try vite-plugin-manifest-sri, but by inspection it appears it will have the same issue.
In any case, certainly looking forward to figuring out a good way to support SRI and CSP with a statically generated single page Vue application. If anyone can help me understand and configure a build without the additional Javascript, I'd greatly appreciate it. Alternately, if there is a mechanism for ensuring that transformIndexHtml or some similar hook could run AFTER the .js files' final content is complete, I'll be happy to help update the plugins. I have so far been unable to locate where in vite or the vue plug-in this "extra code" is added, so if anyone on this thread already has that dialed in, guidance is appreciated.
And, bottom line: Thanks to everyone involved, with both Vite and the various existing SRI plug-ins; I appreciate what you have done here. Pinging for awareness, it looks like @estahn may take [over as maintainer]((https://github.com/JonasKruckenberg/rollup-plugin-sri/issues/393) for @JonasKruckenberg, and @aral is already in this thread.
-Tim
@TimJohns I'm not sure vite-plugin-manifest-sri is susceptible to the problem you mentioned, as it uses writeBundle which is "the last hook of the output generation phase".
However, this plugin is meant to be used with a backend integration, and not for apps where Vite generates index.html as well.
Has there been any discussions about this?
I'm thinking of trying to write a plugin for augmenting dynamic import capabilities, but it doesn't look like it would be possible.
As far as I know, the only way would be to inject a configurable document.createElement('script') based import() shim that would be able to know each bundles final contents, (or read a precomputed map of bundle ids to hashes), and include it on the script element. Anyways that's what webpack seems to be doing 😅.
From the plugin api docs it seems possible to rewrite import() statements to something else, but I can't tell if we'd have access to the bundles at that point. Can anyone advise?
In my case, The vite-plugin-sri and rollup-plugin-sri plugins are not work.
In transformIndexHtml generateBundle hooks, we get old content with script chunks.
Because the vite:build-import-analysis built-in plugin will override some content in generateBundle hook.
At the same time, the order of user-configured plugins cannot be later than that of built-in plugins.
https://github.com/vitejs/vite/blob/733fab8548e363fecc04c096e21a3a18abf62dd4/packages/vite/src/node/plugins/index.ts#L100
In my case, The vite-plugin-sri and rollup-plugin-sri plugins are not work.
In
transformIndexHtmlgenerateBundlehooks, we get old content with script chunks. Because thevite:build-import-analysisbuilt-in plugin will override some content ingenerateBundlehook. At the same time, the order of user-configured plugins cannot be later than that of built-in plugins.https://github.com/vitejs/vite/blob/733fab8548e363fecc04c096e21a3a18abf62dd4/packages/vite/src/node/plugins/index.ts#L100
I make a plugin to resolve this problem https://github.com/yoyo930021/vite-plugin-sri3
Hi,
it seems to me that both rollup-plugin-sri and vite-plugin-sri are inactive and haven't been updated in a long time - maybe that could be the motivation to include this as part of standard vite build? (I agree with somebody up the thread that there is basically no reason not to have SRI and it should be on by default...)
If the Vite team is interested, I'm willing to submit a PR by integrating the plugin.
Hey all, this seems a bit late - but this sort of ties into the whole CSP & SRI conversations that's happening here:
I've just released V1 of vite-plugin-csp-guard - Handles your CSP, and allows you to hash at dev and build time.
Check it out
Lots of documentation here, however planning to add more, especially when concerning SRI
Repo is here
Please check it out - any feedback is welcome!
FYI, vite-plugin-sri has been archived. So I feel the need to do this is even higher now.
@RockiRider does your plugin do SRI as well? The way I see it, CSP and SRI are orthogonal (though both useful!)
To continue, I'd be willing to help with this as well, @yoyo930021 also said they'd be willing to submit a PR.
As this discussion is long and hard to follow, let me tag a core team member - @bluwy, sorry if this is spam, but could you please chime in as to what Vite team thinks? If there are people willing to make a PR that would still be work for you, but I think we would appreciate an official stance on whether this should be part of Vite. Thanks!
any updates or modern workarounds guys? 😅
for security reason, we should Have this feature, both for generated and dynamic chunks.
Also would like this in Vite for moving over one of the last wepback projects we've got.
The has workaround tag should probably be removed with the main 2 plugins that served as workarounds no longer being maintained
An update for you all v2.0.0 of vite-plugin-csp-guard supports SRI.
Disclaimer There are some limitations though:
If you are lazy loading/code splitting, this is fine and the main index.js file will have an integrity hash and these lazy modules will load just fine - however these loaded modules that are added at runtime into the DOM cannot be marked by the integrity attribute.
For completeness it would be nice if this was possible, however since they are loaded in by the main index.js bundle which is already hashed, this is still better than nothing
Here are the api docs. Just needs some light config in the vite.config.ts and you should be good to go!
Try it out and let me know what you think!
Due to SRI requirements by partners I am integrating with, I may be forced to move back to using Webpack after migrating to Vite just recently. I'm using Vite through the vite_rails ruby gem and the current workaround (https://github.com/ElMassimo/vite-plugin-manifest-sri) depends on an old branch of vite_rails that does not work for me. The author @ElMassimo says Vite should provide native support for SRI and for that reason won't fix/rebase, which I think is sensible.
I'm not in capacity to provide PR's or even guess about how this should be done, so unfortunately, I'm unable to contribute myself. I don't want this to come across as a rant - I just want to say that this may happen to others, and being able to pass a security scan to access APIs by certain vendors, maybe a showstopper for more people than just me.
Otherwise, thanks for a fantastic build tool!
I've checked how SRI works for ESM scripts and it seems we need to generate importmaps for it. The integrity attribute can be used for the top level module, but that script can contain import statements. So just having the integrity attributes set is not sufficient.
Import maps integrity proposal (https://github.com/WICG/import-maps/issues/221, https://github.com/whatwg/html/pull/10269) allows us to specify integrity for imports and is supported by Chrome 127+, Safari 18+ (not supported by Firefox yet).
I'm not sure about making this builtin as IIUC SRI only makes sense when you serve the HTML on your server and you serve assets on a different server you don't have full-control of.
But I think moving the generateBundle hook of the vite:build-import-analysis built-in plugin between these two plugins would be nice.
https://github.com/vitejs/vite/blob/733fab8548e363fecc04c096e21a3a18abf62dd4/packages/vite/src/node/plugins/index.ts#L92-L93
Then a plugin can easily implement injecting the importmaps tags / integrity attributes.
I've checked how SRI works for ESM scripts and it seems we need to generate importmaps for it.
FWIW the approach taken by vite_ruby's experimental branch doesn't involve importmaps, but rather puts the digests on the preload tags. https://github.com/ElMassimo/vite_ruby/commit/0b3142cd9d569a5f56821f53cdade337779bb0c1#diff-676829207c8e38e54f9a846457fdacf4b034723561074343e2835252549b6035R86-R93 (NB i can't vouch that these digests are enforced)