nuxt-modules / security

πŸ›‘ Automatically configure your app to follow OWASP security patterns and principles by using HTTP Headers and Middleware
https://nuxt-security.vercel.app/
MIT License
826 stars 60 forks source link

Entry CSS integrity issues on CDN #528

Closed ptdev closed 2 months ago

ptdev commented 2 months ago

Hi,

We're trying to add a CDN to our project but once this CSS gets served from the CDN we get the following security issue:

Subresource Integrity: The resource 'https://staging-cdn.***********.com/_nuxt/entry.D43X-ZjV.css' has an integrity attribute, but the resource requires the request to be CORS enabled to check the integrity, and it is not. The resource has been blocked because the integrity cannot be enforced.

For some reason, only this single entry.*.css gives the error. And after looking at the page source, it appears as this may be because the link tag for this CSS file doesn't have crossorigin parameter as the rest of the files (?). See screenshot:

Screenshot 2024-09-23 at 13 01 40

Now, I'm not sure if this is the actual cause but was just wondering if there is a reason that this particular CSS link tag doesn't have the crossorigin parameter in it, or if there is any option to enable it.

Thank you, cheers.

vejja commented 2 months ago

Hi @ptdev You need to have the crossorigin: anonymous value in the tag. It is normally the case by default with Nuxt though. How did you include this file?

ptdev commented 2 months ago

Hi @vejja

Thanks for the quick reply. But I'm not adding this file (or any CSS) manually anywhere.

All I have is some files on the css property inside nuxt.config.ts.

So I'm guessing that entry.*.css is automatically added by nuxt (?)

vejja commented 2 months ago

Ah ok, I think I understand: you are building the website HTML for a given domain, and then manually moving only the CSS and JS files to another CDN, is that right ? Normally all static assets are supposed to be served from the same origin, otherwise you'll get into crossorigin limitations. I do believe that Nuxt has a cdnURL option for this though, you should try that.

ptdev commented 2 months ago

Hi,

Yes, and we are using app.cdnURL: 'staging-cdn.ourdomain.com' on nuxt config.

We're not copying any files to the CDN host. The CDN we're trying (gcore.com) works by having us create a CNAME that is then pointed to their server. Requests to that CNAME then fetch and cache the files on their CDN.

vejja commented 2 months ago

Ok, very clear. The issue is not on our end, and I'm not sure where it could come from. I found this on the Vite repo: https://github.com/vitejs/vite/pull/17930, so apparently something similar was fixed upstream recently and it looks like it was included in the latest Nuxt version. Which version of Nuxt are you using?

ptdev commented 2 months ago

Hi,

We're using the latest nuxt version (v3.13.2).

That issue does indeed appear to be the same or similar to what we're getting.

After having navigated a bit through our site, other CSS files eventually get the same error (so, not just the entry js file as initially reported).

Apparently, when navigating between pages and Nuxt dynamically adds/removes CSS files, then the link tag is added with the crossorigin parameter. (see screenshot)

Screenshot 2024-09-23 at 15 33 02

But when refreshing the browser and loading from the server, Nuxt adds the CSS link tags without crossorigin, which I assume is what is causing this issue with CDNs. (see screenshot)

Screenshot 2024-09-23 at 15 28 19

We removed our lockfile and reinstalled all dependencies to see if vite somehow got updated, but we still get the same issue, even with all latest packages.

ptdev commented 2 months ago

Hi again,

Was looking further into this and it appears as it will definitely most likely be a nuxt or vite issue.

I've opened an issue on Nuxt's repo with a better repro link and description of the issue.

Closing here, thanks for the hints πŸ‘

Baroshem commented 2 months ago

Thanks once again @vejja for jumping into this πŸ’š

vejja commented 2 months ago

FYI @ptdev - I could reproduce and confirm the issue. The upgrade to Vite 5.4.7 does not solve the problem.

As far as providing an immediate workaround, I can only see 2 options: 1- Not using your CDN subdomain for static assets. Serving everything from the same origin will solve the CORS issue. 2- Not using the Subresource Integrity feature of Nuxt Security, by disabling it with { security: { sri: false } }

vejja commented 2 months ago

@ptdev: Quick update on this one @danielroe just fixed upstream and published a new release of the vue-bundle-renderer. I did run npx nuxi upgrade and I can confirm the issue is fully resolved πŸš€

vejja commented 2 months ago

Ooops sorry @danielroe, talked too fast here. Unless I'm missing something I believe that :

danielroe commented 2 months ago

There is one more place we need to update it...

danielroe commented 2 months ago

See https://github.com/nuxt/nuxt/pull/29138. I'd appreciate if you have a look in the rest of the renderer file to see if there are other places we should be adding crossorigin attributes.

vejja commented 2 months ago

See nuxt/nuxt#29138. I'd appreciate if you have a look in the rest of the renderer file to see if there are other places we should be adding crossorigin attributes.

From a security perspective, subresource integrity hashes are only valid

The W3C RFC provides that other tags may be added to the list in the future, but it is not part of the standard currently so we only add the integrity attribute on the elements listed above.

In summary we don't need crossorigin on anything other than script and link for SRI to be compatible with crossorigin deployments.

vejja commented 2 months ago

@danielroe : To be clear I believe it's only on <link rel="stylesheet"> that we would need it. See screenshot below after the vue-bundle-renderer hotfix:

Capture d’écran 2024-09-24 aΜ€ 14 01 59

ptdev commented 2 months ago

Hi,

Thanks for the updates but the issue still appears to remain the same on my end. 😞

I forked the original reproduction that was posted on the issue at Nuxt's repo:

https://stackblitz.com/edit/nuxt-starter-d6e555?file=README.txt

Ran npx nuxi upgrade as suggested but when loading a page directly from the server the CSS links still do not have the crossorigin attribute.

See screenshot:

Screenshot 2024-09-24 at 14 19 58

Only when navigating from another page, the crossorigin attribute is correctly defined.

danielroe commented 2 months ago

Yes, you'll need to wait for https://github.com/nuxt/nuxt/pull/29138 to be released first πŸ™

vejja commented 2 months ago

Daniel, not sure if feasible but if yes - would you mind backporting it to 3.14 ?

danielroe commented 2 months ago

for sure! I'm backporting all non-breaking changes (features as well as bugfixes)

vejja commented 2 weeks ago

Hi @ptdev Nuxt 3.14 was released last week, this now includes the crossorigin fix I didn’t test it myself but it should now solve your issue. Let me know !

ptdev commented 2 weeks ago

Hi @vejja

Yes, we've updated to 3.14 and can confirm that we can now use a CDN through the cdnUrl parameter without any issues.

Thanks for everything, cheers! πŸ‘