vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.75k stars 6.21k forks source link

Add native support for SRI #2377

Open Exelord opened 3 years ago

Exelord commented 3 years ago

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

aral commented 3 years ago

@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.)

Exelord commented 3 years ago

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 :)

aral commented 3 years ago

@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

aral commented 3 years ago

Quick heads up: I’m rolling my own very simple Vite plugin. Will update once it’s ready.

aral commented 3 years ago

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

patak-dev commented 3 years ago

@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

Exelord commented 3 years ago

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.

pepa-linha commented 3 years ago

Is it possible generate SRI directly to manifest file? Not just change in index HTML file (which I don't use it).

ElMassimo commented 2 years ago

@pepa-linha Created vite-plugin-manifest-sri, which might be useful for your use case.

pepa-linha commented 2 years ago

@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)

AdminHcat commented 2 years ago

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 integrityoption of VueCLI

eloiqs commented 1 year ago

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 🙏 !

TimJohns commented 1 year ago

"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

ElMassimo commented 1 year ago

@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.

eloiqs commented 1 year ago

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?

yoyo930021 commented 11 months ago

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

yoyo930021 commented 11 months ago

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

I make a plugin to resolve this problem https://github.com/yoyo930021/vite-plugin-sri3

marekdedic commented 9 months ago

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...)

yoyo930021 commented 9 months ago

If the Vite team is interested, I'm willing to submit a PR by integrating the plugin.

RockiRider commented 3 months ago

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!

marekdedic commented 2 months ago

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!)

marekdedic commented 2 months ago

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!

atomeon commented 1 month ago

any updates or modern workarounds guys? 😅

mutongwu commented 1 month ago

for security reason, we should Have this feature, both for generated and dynamic chunks.