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

Nonce not applied to deferred scripts on direct page loads #5539

Closed
1 task done
jvanst opened this issue Feb 22, 2023 · 10 comments
Closed
1 task done

Nonce not applied to deferred scripts on direct page loads #5539

jvanst opened this issue Feb 22, 2023 · 10 comments
Labels
bug Something isn't working feat:deferred

Comments

@jvanst
Copy link

jvanst commented Feb 22, 2023

What version of Remix are you using?

1.13.0

Are all your remix dependencies & dev-dependencies using the same version?

  • Yes

Steps to Reproduce

Reproduction repository: https://github.com/jvanst/remix-nonce-bug
Stackblitz: https://stackblitz.com/edit/remix-nonce-bug

Here is a diff of the changes to the base scaffold: jvanst/remix-nonce-bug@e6dcfd0

  • Add content security policy to all responses responseHeaders.set('Content-Security-Policy', `script-src 'self' 'nonce-${NONCE}';`) in entry.server.tsx
  • Add nonce value to renderToPipeableStream() in entry.server.tsx
  • Add nonce value to <ScrollRestoration />, <Scripts />, <LiveReload /> inside root.tsx
  • Create a route with deferred content (i.e /defer)
  • Load route directly (http://localhost:3000/defer) and it throws the following CSP error:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-sample-nonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-7fy19ExJPgqP4hkOQHlXdrQO5jReqP/4bYcdVa14Wdc='), or a nonce ('nonce-...') is required to enable inline execution.

This is inconsistent because if you load http://localhost:3000 and navigate with a <Link> to the deferred page, no such errors occurs.

Our enterprise requires nonces on all inlined scripts so this stops our defer usage until its resolved 🙂. Hoping I can find time to dig through this one more deeply.

Expected Behavior

Deferred content is loaded with nonce value

Actual Behavior

Throws error:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'nonce-sample-nonce'". Either the 'unsafe-inline' keyword, a hash ('sha256-7fy19ExJPgqP4hkOQHlXdrQO5jReqP/4bYcdVa14Wdc='), or a nonce ('nonce-...') is required to enable inline execution.

In production mode the content fails to load.

@jvanst
Copy link
Author

jvanst commented Feb 22, 2023

This may be a duplicate of #5156 but it made no mentioned of difference in behaviour between navigating via link, and loading the route directly

@github-actions
Copy link
Contributor

This issue has been automatically marked stale because we haven't received a response from the original author in a while 🙈. This automation helps keep the issue tracker clean from issues that are not actionable. Please reach out if you have more information for us or you think this issue shouldn't be closed! 🙂 If you don't do so within 7 days, this issue will be automatically closed.

@github-actions github-actions bot added the needs-response We need a response from the original author about this issue/PR label Apr 23, 2023
@jvanst
Copy link
Author

jvanst commented Apr 27, 2023

Still relevant.

@github-actions github-actions bot removed the needs-response We need a response from the original author about this issue/PR label Apr 27, 2023
@brophdawg11
Copy link
Contributor

This should be fixed by #6389 and available in the next release

@brophdawg11 brophdawg11 added bug Something isn't working awaiting release This issue has been fixed and will be released soon and removed bug:unverified labels Jun 14, 2023
@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version v0.0.0-nightly-ad9adee-20230615 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version v0.0.0-nightly-12440f3-20230616 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 1.18.0-pre.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 1.18.0 which involves this issue. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@brophdawg11 brophdawg11 removed the awaiting release This issue has been fixed and will be released soon label Dec 14, 2023
@Mihai-github
Copy link

I am still encountering this issue while running Remix in a Hydrogen project.

Here's my package.json

"dependencies": {
    "@hookform/resolvers": "^3.3.4",
    "@remix-run/react": "^2.5.1",
    "@remix-run/server-runtime": "^2.5.1",
    "@shopify/cli": "3.52.0",
    "@shopify/cli-hydrogen": "^7.0.0",
    "@shopify/hydrogen": "~2024.1.0",
    "@shopify/remix-oxygen": "^2.0.3",
    "graphql": "^16.6.0",
    "graphql-tag": "^2.12.6",
    "isbot": "^3.6.6",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-hook-form": "^7.50.0",
    "swiper": "^11.0.5",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@remix-run/dev": "^2.5.1",
    "@remix-run/eslint-config": "^2.5.1",
    "@shopify/oxygen-workers-types": "^4.0.0",
    "@shopify/prettier-config": "^1.1.2",
    "@tailwindcss/forms": "^0.5.3",
    "@tailwindcss/typography": "^0.5.9",
    "@total-typescript/ts-reset": "^0.4.2",
    "@types/eslint": "^8.4.10",
    "@types/react": "^18.2.22",
    "@types/react-dom": "^18.2.7",
    "eslint": "^8.20.0",
    "eslint-plugin-hydrogen": "0.12.2",
    "postcss": "^8.4.21",
    "postcss-import": "^15.1.0",
    "postcss-preset-env": "^8.2.0",
    "prettier": "^2.8.4",
    "tailwindcss": "^3.4.1",
    "typescript": "^5.2.2"
  },

and my entry.server.tsx

import type {EntryContext} from '@shopify/remix-oxygen';
import {RemixServer} from '@remix-run/react';
import isbot from 'isbot';
import {renderToReadableStream} from 'react-dom/server';
import {createContentSecurityPolicy} from '@shopify/hydrogen';

export default async function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext,
) {
  const {nonce, header, NonceProvider} = createContentSecurityPolicy();

  const body = await renderToReadableStream(
    <NonceProvider>
      <RemixServer context={remixContext} url={request.url} />
    </NonceProvider>,
    {
      nonce,
      signal: request.signal,
      onError(error) {
        // eslint-disable-next-line no-console
        console.error(error);
        responseStatusCode = 500;
      },
    },
  );

  if (isbot(request.headers.get('user-agent'))) {
    await body.allReady;
  }

  responseHeaders.set('Content-Type', 'text/html');
  responseHeaders.set('Content-Security-Policy', header);

  return new Response(body, {
    headers: responseHeaders,
    status: responseStatusCode,
  });
}

@brophdawg11
Copy link
Contributor

@Mihai-github would you mind opening a new issue with a reproduction?

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

No branches or pull requests

3 participants