Next.js: [Feature request] Support for SRI

Created on 1 Feb 2020  路  2Comments  路  Source: vercel/next.js

Feature request

Is your feature request related to a problem? Please describe.

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch (for example, from a CDN) are delivered without unexpected manipulation.

Describe the solution you'd like

Implement webpack plugin (https://www.npmjs.com/package/webpack-subresource-integrity) as default, or under a flag just for production environment.

Thanks to it every external resource should have generated integrity hash and specified crossorigin policy. Example:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

Describe alternatives you've considered

There are other alternative plugins as well. We can also develop an in-house solution.
This feature can also be handled "per app", however, in my opinion, things related to the security of resources loading should be handled by the framework.

Most helpful comment

I'm the principal author of webpack-subresource-integrity, I would also like to see this feature and could maybe help build it.

The snippet above is a start, except it should only be executed when !isServer. It will enable SRI for lazy-loaded (dynamically imported) chunks, but of course that doesn't help much when the top-level assets (those loaded from HTML files) don't carry hashes.

Without knowing much about next.js code, it looks like these hashes will have to be extracted from the result of the client build (somewhere around here?) and injected into the HTML pages (here?).

How would this data be ferried from one place to the other? I've seen mention of a manifest for this purpose, which should do the trick for the production server. Would that be a good place for it? For static builds the hashes are not needed in a manifest as they will already be baked into the HTML.

I've also seen mention of the client-side router injecting <script> tags; these would need treatment as well. It could probably use the hashes that soon will be exposed on the __webpack_require__ object, assuming that the router feature builds on top of Webpack chunks. Where does that code live?

One other consideration is that when enabled, the Cache-Control: no-transform header should be set. I assume this is straightforward now that next.js has a facility for managing server headers. People who export static pages and host them without TLS might have to be told that they need to ensure this header is set, or opt out of the feature.

All 2 comments

How do I implement this "per app" for now until it's made part of the framework? My next.config.js:

const withPrefresh = require('@prefresh/next')
const SriPlugin = require('webpack-subresource-integrity')

module.exports = withPrefresh({
  webpack(config, { dev, isServer }) {

    // Preact config that is not relevant

    config.output.crossOriginLoading = 'anonymous'
    config.plugins.push(new SriPlugin({
        hashFuncNames: ['sha256', 'sha384'],
        enabled: true,
    }))

    return config
  },
})

I'm the principal author of webpack-subresource-integrity, I would also like to see this feature and could maybe help build it.

The snippet above is a start, except it should only be executed when !isServer. It will enable SRI for lazy-loaded (dynamically imported) chunks, but of course that doesn't help much when the top-level assets (those loaded from HTML files) don't carry hashes.

Without knowing much about next.js code, it looks like these hashes will have to be extracted from the result of the client build (somewhere around here?) and injected into the HTML pages (here?).

How would this data be ferried from one place to the other? I've seen mention of a manifest for this purpose, which should do the trick for the production server. Would that be a good place for it? For static builds the hashes are not needed in a manifest as they will already be baked into the HTML.

I've also seen mention of the client-side router injecting <script> tags; these would need treatment as well. It could probably use the hashes that soon will be exposed on the __webpack_require__ object, assuming that the router feature builds on top of Webpack chunks. Where does that code live?

One other consideration is that when enabled, the Cache-Control: no-transform header should be set. I assume this is straightforward now that next.js has a facility for managing server headers. People who export static pages and host them without TLS might have to be told that they need to ensure this header is set, or opt out of the feature.

Was this page helpful?
0 / 5 - 0 ratings