mcansh / http-helmet

easily add CSP and other security headers to your web application.
https://www.npmjs.com/package/@mcansh/http-helmet
16 stars 0 forks source link

[Cloudflare Pages] max-age always 0 #107

Closed TheAifam5 closed 2 months ago

TheAifam5 commented 2 months ago

Hey,

I noticed a strange issue, that might be related to both, Remix and '@mcansh/http-helmet', but I am unsure here.

Every other property, except max-age is set. This does not happen when running locally. Do you maybe have an idea what went wrong?

Best regards, TheAifam5

Code:

  const secureHeaders = createSecureHeaders({
    'Content-Security-Policy': {
      baseUri: ["'none'"],
      defaultSrc: ["'self'"],
      objectSrc: ["'none'"],
      scriptSrc: [
        "'self'",
        "'unsafe-inline'",
        "'strict-dynamic'",
        `'nonce-${nonce}'`,
        loadContext.hasAnalytics ? 'static.cloudflareinsights.com' : '',
      ],
      connectSrc: [
        "'self'",
        ...(process.env.NODE_ENV === 'development' ? ['ws:'] : []),
        loadContext.hasAnalytics ? `cloudflareinsights.com` : '',
      ],
      requireTrustedTypesFor: ["'script'"],
    },
    'Cross-Origin-Embedder-Policy': 'require-corp',
    'Cross-Origin-Opener-Policy': 'same-origin',
    'Cross-Origin-Resource-Policy': 'same-origin',
    'Strict-Transport-Security': {
      maxAge: 31536000,
      includeSubDomains: true,
      preload: true,
    },
    'X-Frame-Options': 'DENY',
    'X-Content-Type-Options': 'nosniff',
    'Referrer-Policy': 'strict-origin-when-cross-origin',
    'Permissions-Policy': permissionsPolicy,
  });

Response headers on Cloudflare:

HTTP/3 200 
date: Sun, 07 Jul 2024 13:22:40 GMT
content-type: text/html
strict-transport-security: max-age=0; includeSubDomains; preload
cf-placement: local-EWR
content-security-policy: base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'unsafe-inline' 'strict-dynamic' 'nonce-WYpyex2to6tcDU3dVlxnO6BvJFYbfNcgZF5OPqfE55I=' static.cloudflareinsights.com; connect-src 'self' cloudflareinsights.com; require-trusted-types-for 'script'
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
permissions-policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), layout-animations=(), legacy-image-formats=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), oversized-images=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), speaker-selection=(), sync-xhr=(), unoptimized-images=(), unsized-media=(), usb=(), web-share=(), xr-spatial-tracking=()
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
x-frame-options: DENY
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=OSTxEbNn%2F69g5%2BIVvz14cPyq%2Fyfll88W3A88sT6pNAyjgiG2cpgNRYJzAMz2lC2JbsysAdS7WYr5BYsZevhel1X7gf5d5y%2BhQQYxrumAW7mHw%2FWUgpjkie%2F9BYcowqQ%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
vary: Accept-Encoding
cf-cache-status: DYNAMIC
priority: u=1,i=?0
server: cloudflare
cf-ray: 89f8250b9b398c09-EWR
content-encoding: br
alt-svc: h3=":443"; ma=86400

Response headers from localhost using Remix vite:dev:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
content-security-policy: base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'unsafe-inline' 'strict-dynamic' 'nonce-hr/kvag1ZNkYOYezslRvkd3kCUWpD/tg+jE3rPY4btg='; connect-src 'self' ws:; require-trusted-types-for 'script'
content-type: text/html
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
permissions-policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), layout-animations=(), legacy-image-formats=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), oversized-images=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), speaker-selection=(), sync-xhr=(), unoptimized-images=(), unsized-media=(), usb=(), web-share=(), xr-spatial-tracking=()
referrer-policy: strict-origin-when-cross-origin
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-content-type-options: nosniff
x-frame-options: DENY
Date: Sun, 07 Jul 2024 13:26:53 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked

Response headers from localhost using wrangler server (after build, like in CI/CD pipeline & deployment):

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/html
Content-Encoding: gzip
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
content-security-policy: base-uri 'none'; default-src 'self'; object-src 'none'; script-src 'self' 'unsafe-inline' 'strict-dynamic' 'nonce-tJF8R+AXkKqiObo8300ECGsBvdj4/faPncwxtSYGv6U='; connect-src 'self' ws:; require-trusted-types-for 'script'
cross-origin-embedder-policy: require-corp
cross-origin-opener-policy: same-origin
cross-origin-resource-policy: same-origin
permissions-policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), layout-animations=(), legacy-image-formats=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), oversized-images=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), speaker-selection=(), sync-xhr=(), unoptimized-images=(), unsized-media=(), usb=(), web-share=(), xr-spatial-tracking=()
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
x-frame-options: DENY
TheAifam5 commented 2 months ago

Nevermind, cloudflare setting.