SRI applied incorrectly to <link rel="preload|modulepreload">
Environment
- Operating System: `Windows`
- Node Version: `v22.12.0`
- Nuxt Version: `4.0.3`
- Nitro Version: `2.12.4`
- Package Manager: `[email protected]`
Nuxt Security Version
2.2.0
Default setup used?
Yes, the bug happens even if the security option is not customized
Security options
security: {
headers: {
crossOriginResourcePolicy: false,
crossOriginOpenerPolicy: false,
crossOriginEmbedderPolicy: false,
contentSecurityPolicy: {
'base-uri': false,
'font-src': false,
'form-action': false,
'frame-ancestors': false,
'img-src': false,
'object-src': false,
'script-src-attr': false,
'style-src': false,
'script-src': cspScriptSrc,
'upgrade-insecure-requests': false,
},
originAgentCluster: false,
referrerPolicy: false,
strictTransportSecurity: false,
xContentTypeOptions: false,
xDNSPrefetchControl: false,
xDownloadOptions: false,
xFrameOptions: false,
xPermittedCrossDomainPolicies: false,
xXSSProtection: false,
permissionsPolicy: false,
},
requestSizeLimiter: false,
rateLimiter: false,
xssValidator: false,
corsHandler: false,
allowedMethodsRestricter: false,
hidePoweredBy: false,
basicAuth: false,
nonce: false,
removeLoggers: false,
ssg: false,
},
Reproduction
nitro: { esbuild: { options: { target: 'esnext', }, }, prerender: { crawlLinks: false, routes: ['/'], ignore: [], }, },
Description
When enabling SRI in nuxt-security, it seems that and tags are also being matched by the regex in runtime/nitro/plugins/20-subresourceIntegrity.js:
const LINK_RE = /<link((?=[^>]+\brel="(?:stylesheet|preload|modulepreload)")(?=[^>]+\bhref="([^"]+)")(?![^>]+\bintegrity="[\w-+/=]+")[^>]+)>/g;
This causes integrity attributes to be injected into preload and modulepreload links. However, according to the HTML spec and current browser implementations, Subresource Integrity is not supported for preload/modulepreload links, and integrity attributes there are ignored. Reference: WHATWG Fetch Spec
Additional context
Logs
The integrity attribute is currently ignored for preload destinations that do not support subresource integrity.
Hey @MinakoKitani
Thanks for reporting this issue. As you have already looked into the potential solution, maybe you would be interested in creating a PR with a fix? :)
Hi @MinakoKitani
The reason for including preload and modulepreload links is documented here:
https://github.com/Baroshem/nuxt-security/blob/main/src/runtime/nitro/plugins/30-cspSsgHashes.ts#L75
We tried to implement the RFC as correctly as possible, but there might be some glitches.
I'm not 100% sure what the Chromium discussion list was exactly trying to fix.
In your case, I can see that:
- the
modulepreloadlinks were correctly verified and passed the integrity check - the
preloadon the json link generated a simple warning, informing you that verification was ignored because JSON is a destination that Chromium currently does not support
What is the exact issue you encountered? Did it block your application from running properly?