Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No more meta http-equiv since 0.13.0 #178

Closed
GreyXor opened this issue Jul 17, 2023 · 21 comments · Fixed by #181
Closed

No more meta http-equiv since 0.13.0 #178

GreyXor opened this issue Jul 17, 2023 · 21 comments · Fixed by #181
Labels
bug Something isn't working

Comments

@GreyXor
Copy link

GreyXor commented Jul 17, 2023

Version

{
	"devDependencies": {
		"nuxt": "^3.6.3",
		"nuxt-security": "^0.13.0" // also tried 0.13.1 and 0.14.0
	}
}

Reproduction Link

Steps to reproduce

Install nuxt-security >= 0.13.0
I'm using all default and running nuxt generate.

with version 0.12.0 it works

What is Expected?

meta http-equiv added in index.html

What is actually happening?

No meta http-equiv

@GreyXor GreyXor added the bug Something isn't working label Jul 17, 2023
@Baroshem
Copy link
Owner

Hey @GreyXor

Thanks for reporting this issue. Would you be interested in investingating this issue and creating a pull request? :)

@GreyXor
Copy link
Author

GreyXor commented Jul 17, 2023

Hey @GreyXor

Thanks for reporting this issue. Would you be interested in investingating this issue and creating a pull request? :)

Although my expertise with the Nuxt module is limited, I'm willing to give it a try. However, would you have any ideas or suggestions regarding the possible source of this bug?

@Baroshem
Copy link
Owner

Yes,

The biggest change that was introduced in these versions was the refactor of middlewares and headers into global and route rules.

v0.12.0...v0.13.0

@Baroshem
Copy link
Owner

So I think that this issue is somehow related to the data passing to the plugin as the whole plugin has not changed at all.

@trijpstra-fourlights
Copy link
Contributor

It seems that

delete (securityOptions as any).headers;
is the culprit.

JS passes objects by reference so deleting the headers there will impact all other subsequent usages of securityOptions as well.

Seems the deletion is only there because of the for-loop where you don't want to handle headers as middleware.
So quick fix would be to:

  • don't delete headers and skip when encountering headers in the loop
  • or create a local copy omitting the headers and loop through that

But IMO it's code smell and the loop should be rewritten so that it loops through the SECURITY_MIDDLEWARE_NAMES global variable and see from there if it's defined in the securityOptions.

@Baroshem
Copy link
Owner

Hey @trijpstra-fourlights

Thanks for this tip! I have already created a fix for that but I also looked at the CSP on SSG being generated incorrectly (there is only script src there while other headers should be set.

@Baroshem
Copy link
Owner

There was a problem in two places:

  1. The one mentioned by @trijpstra-fourlights Thanks for that 💚
  2. Second one in the CSP options passed to the plugin (only .value was used not the whole object)

Now it should work as expected:

image

@Baroshem Baroshem mentioned this issue Jul 18, 2023
6 tasks
@Baroshem
Copy link
Owner

@GreyXor Could you check the 0.14.1 version?

@GreyXor
Copy link
Author

GreyXor commented Jul 18, 2023

@Baroshem, thanks, seems better, although I have another problem but maybe related.
I have followed this documentation : https://nuxt-security.vercel.app/security/headers#nonce-support
and then I have this in my nuxt config :

  security: {
    nonce: true,
    headers: {
      contentSecurityPolicy: {
        'style-src': [
          "'self'",  // fallback value for older browsers, automatically removed if `strict-dynamic` is supported.
          "'nonce-{{nonce}}'",
        ],
        'script-src': [
          "'self'",  // fallback value for older browsers, automatically removed if `strict-dynamic` is supported.
          "'nonce-{{nonce}}'",
          "'strict-dynamic'"
        ],
        'script-src-attr': [
          "'self'",  // fallback value for older browsers, automatically removed if `strict-dynamic` is supported.
          "'nonce-{{nonce}}'",
          "'strict-dynamic'"
        ]
      }
    }
  },

but {{nonce}} literaly appear in generated code

<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; font-src 'self' https: data:; form-action 'self'; img-src 'self' data:; object-src 'none'; script-src-attr 'self' 'nonce-{{nonce}}' 'strict-dynamic'; style-src 'self' 'nonce-{{nonce}}'; upgrade-insecure-requests ; script-src 'self' 'nonce-{{nonce}}' 'strict-dynamic' 'sha256-xJJj9w6qgxhSKMyZfS3zCVu22GSxDA9p/seYxCqfC/0=' 'sha256-+98blmkAXZ200NERYkCs+Dh/tyOjTMb5e1IBMiB/wl8='"><

@Baroshem
Copy link
Owner

These two things were developed independently (CSP for SSG was created about two versions before) while this new noonce support was created in the last few days.

@trijpstra-fourlights Would you be up for helping @GreyXor with the issue he is encountering? I would really appreciate it :)

@trijpstra-fourlights
Copy link
Contributor

Sure, I'll take a look. I suspect it's because both nitro plugins hook into the same hook so and the ordering is not explicitly defined. So the nonce handler is firing before the meta-equiv is added by cspSsg.

@GreyXor
Copy link
Author

GreyXor commented Jul 18, 2023

Sure, I'll take a look. I suspect it's because both nitro plugins hook into the same hook so and the ordering is not explicitly defined. So the nonce handler is firing before the meta-equiv is added by cspSsg.

As seen here: https://nitro.unjs.io/guide/plugins
Can we just prefix it with number order ?

@trijpstra-fourlights
Copy link
Contributor

Sure, that should be possible.

I've looked into it, and I'm pretty sure the ssgHandler will need to be made nonce-aware as well.

I'll whip up a PR for this. Will let you know when it's ready.

@trijpstra-fourlights
Copy link
Contributor

@GreyXor could you test with my proposed fixes?

change in your package.json

nuxt-security: "nuxt-security": "github:trijpstra-fourlights/nuxt-security#build/fix/nonce-and-ssg",

and do an npm install (or equivalent)

@GreyXor
Copy link
Author

GreyXor commented Jul 18, 2023

@GreyXor could you test with my proposed fixes?

change in your package.json

nuxt-security: "nuxt-security": "github:trijpstra-fourlights/nuxt-security#build/fix/nonce-and-ssg",

and do an npm install (or equivalent)

Sorry, just this in my package.json ?

yarn install

  "devDependencies": {
    "nuxt": "^3.6.3",
    "nuxt-security": "github:trijpstra-fourlights/nuxt-security#build/fix/nonce-and-ssg",
  }

I got this :

 ERROR  Error while requiring module nuxt-security: Error: Cannot find module '/tmp/nonce/nuxt-security'                                                           12:54:44 PM
Require stack:
- /tmp/nonce/index.js

@trijpstra-fourlights
Copy link
Contributor

It seems that the syntax I provided is for pnpm.

Could you try yarn add -D https://github.com/trijpstra-fourlights/nuxt-security#build/fix/nonce-and-ssg?

@GreyXor
Copy link
Author

GreyXor commented Jul 18, 2023

yarn add -D https://github.com/trijpstra-fourlights/nuxt-security#build/fix/nonce-and-ssg
yarn nuxt dev

ERROR Error while requiring module ~/node_modules/nuxt-security: Error: EISDIR: illegal operation on a directory, read

@trijpstra-fourlights
Copy link
Contributor

Perhaps you'll have to rm -R node_modules first, to remove any previous version. I'm not sure.
It's working for me though.

Running the test fixtures with nuxt generate results in http-equiv meta tag set with set nonce values.

@GreyXor
Copy link
Author

GreyXor commented Jul 18, 2023

Perhaps you'll have to rm -R node_modules first, to remove any previous version. I'm not sure. It's working for me though.

Running the test fixtures with nuxt generate results in http-equiv meta tag set with set nonce values.

even creating a new project doesn't work, not with pnpm nor yarn. If your nonce are visible, that solves the problem. My package pulling issue is something else, thanks !

@Baroshem
Copy link
Owner

Thank you @trijpstra-fourlights for the fix and implementation!

And thank you @GreyXor for testing. I have tested it on my end and it seems to be working correctly on 0.14.2 :)

@trijpstra-fourlights
Copy link
Contributor

Please note that it actually does not make any sense to use nonce in SSG mode, as the security added by nonce values comes purely from the fact that nonces are non-deterministic and generated at runtime (i.e. randomized by the server for each request).

In SSG mode the nonce becomes static as it's generated once at build-time and thus becomes a potential attack vector for XSS.

To use a strict CSP in SSG, you need to whitelist your resources using sha-256 hashes. This is what nuxt-security already does (although it currently only seems to generate these hashes for resources in the <body> tag).

For more information see https://web.dev/strict-csp/#step-1-decide-if-you-need-a-nonce-or-hash-based-csp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants