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

X-Content-Type-Options nosniff duplicated ? #575

Open
GreyXor opened this issue Nov 29, 2024 · 7 comments
Open

X-Content-Type-Options nosniff duplicated ? #575

GreyXor opened this issue Nov 29, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@GreyXor
Copy link

GreyXor commented Nov 29, 2024

Version

nuxt-security: 2.1.4
nuxt: 3.14.1592

Image

Image

Hello, I build an app with pnpm build --preset=cloudflare-pages-static and I see some duplicates entries in _headers.
then that cause cloudflare to send in double some heaeders, that's normal ?

@GreyXor GreyXor added the bug Something isn't working label Nov 29, 2024
@vejja
Copy link
Collaborator

vejja commented Nov 29, 2024

Not normal
Do you have duplicates in dev mode?

@GreyXor
Copy link
Author

GreyXor commented Nov 29, 2024

After I ran pnpm build --preset=cloudflare-pages-static. I have this dist/_headers

/_nuxt/builds/meta/*
  cache-control: public, max-age=31536000, immutable
/_nuxt/builds/*
  cache-control: public, max-age=1, immutable
/sitemap.xsl
  Content-Type: application/xslt+xml
/_nuxt/*
  cache-control: public, max-age=31536000, immutable
/200.html
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL'; script-src 'self' 'strict-dynamic' 'sha256-gA1UKgUEtDt2cidaUsoCZuF2sWpGSFUt2uXOBWMbCZM=' 'sha256-fS31OOiK/d40YbVTuBvQgFn10Npo1aV7bXp3h5YkeKI=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/404.html
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL'; script-src 'self' 'strict-dynamic' 'sha256-gA1UKgUEtDt2cidaUsoCZuF2sWpGSFUt2uXOBWMbCZM=' 'sha256-fS31OOiK/d40YbVTuBvQgFn10Npo1aV7bXp3h5YkeKI=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha256-UdfdXjfVHznHxwWlHuNuP27rkN3lBKcVnhZogpI5r78=' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL'; script-src 'self' 'strict-dynamic' 'sha256-gKRuwZ+smqCIe8ekh9BSEjP/JMiE/HydqXdklskRuSI=' 'sha256-r0Kb+H/sw2Iz9Eook98TRhCAPotgSM7Rt3swxyFA1ck=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx' 'sha384-ylPEr5j/hF/bSw37JlKOi7oibm+rTmVGYTTY86WeIkoyWvuminVkdYb6xtGp7Otk' 'sha384-ymbnSmVFGtrsjQDRc78Nk9nQGIFZf8k8GW0Z+IOnftyCqCN8yLM9bXUAIJEE2z0f' 'sha384-CLIB45fgjg9w1i3EOkUyatVJt21CdR0wzjmJnCuy2wYWk5fDZ7CuPyMc3zMo1PpZ' 'sha384-woIiDj1p8pe5KDYJD5Zhlr3JDN/xpRuDybcKtC+JQRQ48vOCCwV07CjjLH6b8Vx7' 'sha384-GmdH5Y3CkHFK2DwR6PFvawjSdL99LqW6B/dNrFdM6EDbKp7tUXBX+iunzp8HWipz' 'sha384-G1G4K9Cdpsm+OUxwyNecEZXUnk2CkUz270l7cwQaL57caava7SVXtzHzBSd3UInU' 'sha384-e6dRA9EojU+KQVAfHQAg6NuNuaZiVe4cQArItDF+7yfEbmAvC16+nqedrebVDzFL'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/server
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha256-UdfdXjfVHznHxwWlHuNuP27rkN3lBKcVnhZogpI5r78=' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL'; script-src 'self' 'strict-dynamic' 'sha256-df8dhj665lYudfXbvs9oaGlTADm07l26HhpaEHl/jq8=' 'sha256-q1m60j+ht3Y9a0Ev9eFUHO83P7ksur8gevJGx6yIkuM=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx' 'sha384-ylPEr5j/hF/bSw37JlKOi7oibm+rTmVGYTTY86WeIkoyWvuminVkdYb6xtGp7Otk' 'sha384-ymbnSmVFGtrsjQDRc78Nk9nQGIFZf8k8GW0Z+IOnftyCqCN8yLM9bXUAIJEE2z0f' 'sha384-CLIB45fgjg9w1i3EOkUyatVJt21CdR0wzjmJnCuy2wYWk5fDZ7CuPyMc3zMo1PpZ' 'sha384-woIiDj1p8pe5KDYJD5Zhlr3JDN/xpRuDybcKtC+JQRQ48vOCCwV07CjjLH6b8Vx7' 'sha384-GmdH5Y3CkHFK2DwR6PFvawjSdL99LqW6B/dNrFdM6EDbKp7tUXBX+iunzp8HWipz' 'sha384-G1G4K9Cdpsm+OUxwyNecEZXUnk2CkUz270l7cwQaL57caava7SVXtzHzBSd3UInU' 'sha384-e6dRA9EojU+KQVAfHQAg6NuNuaZiVe4cQArItDF+7yfEbmAvC16+nqedrebVDzFL' 'sha384-tJd1zSyyVGXwcklmH1jwMt/dBgC4cBkDaBCdfqu8PRYERQ/IWi/UWD+3qucS+FvB'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/console
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha256-UdfdXjfVHznHxwWlHuNuP27rkN3lBKcVnhZogpI5r78=' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL' 'sha384-2FDO4EtrxO6iDmbhfnnT4LRzGhPIFREAKN4R3qLSNLHgqMf4lh1jqOMg9Hd1HQY7'; script-src 'self' 'strict-dynamic' 'sha256-Uafai4qtsVNcTkdgxrioFMGt5473HSoofwMgC6vOqEA=' 'sha256-80vwQVcHFwAzDTCPEKTLDViuIO6khm8ynHpK/GwXuJQ=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx' 'sha384-ylPEr5j/hF/bSw37JlKOi7oibm+rTmVGYTTY86WeIkoyWvuminVkdYb6xtGp7Otk' 'sha384-ymbnSmVFGtrsjQDRc78Nk9nQGIFZf8k8GW0Z+IOnftyCqCN8yLM9bXUAIJEE2z0f' 'sha384-CLIB45fgjg9w1i3EOkUyatVJt21CdR0wzjmJnCuy2wYWk5fDZ7CuPyMc3zMo1PpZ' 'sha384-woIiDj1p8pe5KDYJD5Zhlr3JDN/xpRuDybcKtC+JQRQ48vOCCwV07CjjLH6b8Vx7' 'sha384-GmdH5Y3CkHFK2DwR6PFvawjSdL99LqW6B/dNrFdM6EDbKp7tUXBX+iunzp8HWipz' 'sha384-G1G4K9Cdpsm+OUxwyNecEZXUnk2CkUz270l7cwQaL57caava7SVXtzHzBSd3UInU' 'sha384-e6dRA9EojU+KQVAfHQAg6NuNuaZiVe4cQArItDF+7yfEbmAvC16+nqedrebVDzFL' 'sha384-J/uFW5rsYYVLm53X0OebMECk5/seFHGWJzh367z3hFM+5YSc/ChXXIvMuAZ56CC+'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/settings
  referrer-policy: no-referrer
  strict-transport-security: max-age=31536000; includeSubDomains; preload;
  x-content-type-options: nosniff
  x-download-options: noopen
  x-frame-options: DENY
  x-permitted-cross-domain-policies: none
  x-xss-protection: 0
  access-control-allow-origin: *
  x-robots-tag: index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1
  cross-origin-resource-policy: same-origin
  cross-origin-opener-policy: same-origin
  cross-origin-embedder-policy: require-corp
  content-security-policy: base-uri 'none'; default-src 'none'; connect-src *; font-src 'self'; form-action 'self'; frame-ancestors 'self'; frame-src 'self'; img-src 'self'; manifest-src 'self'; media-src 'self'; object-src 'none'; script-src-attr 'none'; style-src 'self' 'sha256-UdfdXjfVHznHxwWlHuNuP27rkN3lBKcVnhZogpI5r78=' 'sha384-f03nx78rOCnt6AwELJMV23DoKZkgSc38OV+pGbyjAGJ5fp6iw4cJnouUWcAp0YoL'; script-src 'self' 'strict-dynamic' 'sha256-peq6HdqwADViZy0yHttmVgM3kRT8opnE1Ns7gRzdQJM=' 'sha256-3tFygGBwVe8Pg5A7aNF360JW1nRDyGyectc0kc57p8g=' 'sha256-XMTtN7sjHppnSdg9yFi3iIW2ZYe401Hkaw9C4u4RTO8=' 'sha384-O1ypfnqBHcffeqgUF8m9Qzicp5gzsENWl6MuXGu0fUtLvrEAnF/aB8FCV2BG4XHx' 'sha384-ylPEr5j/hF/bSw37JlKOi7oibm+rTmVGYTTY86WeIkoyWvuminVkdYb6xtGp7Otk' 'sha384-ymbnSmVFGtrsjQDRc78Nk9nQGIFZf8k8GW0Z+IOnftyCqCN8yLM9bXUAIJEE2z0f' 'sha384-CLIB45fgjg9w1i3EOkUyatVJt21CdR0wzjmJnCuy2wYWk5fDZ7CuPyMc3zMo1PpZ' 'sha384-woIiDj1p8pe5KDYJD5Zhlr3JDN/xpRuDybcKtC+JQRQ48vOCCwV07CjjLH6b8Vx7' 'sha384-GmdH5Y3CkHFK2DwR6PFvawjSdL99LqW6B/dNrFdM6EDbKp7tUXBX+iunzp8HWipz' 'sha384-G1G4K9Cdpsm+OUxwyNecEZXUnk2CkUz270l7cwQaL57caava7SVXtzHzBSd3UInU' 'sha384-e6dRA9EojU+KQVAfHQAg6NuNuaZiVe4cQArItDF+7yfEbmAvC16+nqedrebVDzFL' 'sha384-tJd1zSyyVGXwcklmH1jwMt/dBgC4cBkDaBCdfqu8PRYERQ/IWi/UWD+3qucS+FvB'; upgrade-insecure-requests; worker-src 'self';
  origin-agent-cluster: ?1
  x-dns-prefetch-control: off
  permissions-policy: accelerometer=(), autoplay=(), camera=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=()
  content-type: text/html;charset=utf-8
/*
  Referrer-Policy: no-referrer
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload;
  X-Content-Type-Options: nosniff
  X-Download-Options: noopen
  X-Frame-Options: DENY
  X-Permitted-Cross-Domain-Policies: none
  X-XSS-Protection: 0

no. Devmode don't duplicate entries

@vejja
Copy link
Collaborator

vejja commented Nov 29, 2024

Which headers are duplicated? Can't see them above

@GreyXor
Copy link
Author

GreyXor commented Nov 29, 2024

/settings
  x-content-type-options: nosniff

and

/*
  X-Content-Type-Options: nosniff

Also one is uppercase and one other is not
thanks!

@vejja
Copy link
Collaborator

vejja commented Nov 30, 2024

ok got it
the route definitions seem correct
but it looks like cloudflare creates the duplicates when it merges /* with /settings
is that normal?

@GreyXor
Copy link
Author

GreyXor commented Dec 2, 2024

ok got it the route definitions seem correct but it looks like cloudflare creates the duplicates when it merges /* with /settings is that normal?

If in dev mode it's working as expected. that's mean it's a cloudflare issue ? I think so

@vejja
Copy link
Collaborator

vejja commented Dec 2, 2024

I looked at the Cloudflare docs here : https://developers.cloudflare.com/pages/configuration/headers/
They have this section:
Image

This is why the headers are getting duplicated

@pi0 as per you suggestion to track nitrojs/nitro#2909 here:
I'm wondering how Nitro can handle this.
I think the issue with the headers is that each vendor has different priority rules:

  • some will stop at the first match
  • some will process multiple matches
  • when processing multiple matches, some will replace duplicate entries, while others will merge values

Maybe we can start with the Nuxt approach: What is the assumption that routeRules makes for multiple matches?
For clarity let's say that we have the following route rules:

routeRules: {
  '/**': {
    headers: {
      foo: 'bar'
    },
  '/settings': {
    headers: {
      foo: 'baz'
    }
  }
}

Am I correct to assume the /settings page will return header Foo: baz when delivered in SSR by Nitro ?

See Stackblitz here : https://stackblitz.com/~/github.com/vejja/nuxt-starter-uimpbg

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

No branches or pull requests

2 participants