Resources
Content-Security-Policy: script-src directive
Content-Security-Policy: connect-src directive
Background
Referencing the previous post, we have a basic setup for the Content Security Policy (CSP) headers with the script-src
directive in the src/middleware.js file of the project.
Security - Solving the "Content Security Policy (CSP) Header Not Set" in Next.js
Jen C. ・ May 28
Errors and solutions
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'nonce-xxx'
Error message:
Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'nonce-YjQ3MGE2NDEtYTE2ZS00ODU5LTgzYjEtY2I0ODQ0OTQ3YWJi' https://my.domain.com 'strict-dynamic'".
at ./node_modules/next/dist/compiled/@next/react-refresh-utils/dist/runtime.js (react-refresh.js:30:26)
...
Root cause
Because the module used for React Refresh during development contains code that uses eval()
, the current CSP script-src
directive is not sufficient, as it does not include the 'unsafe-eval'
source expression. As shown below:
script-src 'self' 'nonce-${nonce}' ${authUrl} 'strict-dynamic';
Solution
For security reasons, we should not include 'unsafe-eval'
in the production environment. Therefore, we should check the current environment and add 'unsafe-eval'
only when it is not a production environment.
const authUrl = `${myAuthURL.protocol}//${myAuthURL.host}`;
const isProd = process.env.NODE_ENV === 'production';
export function middleware(request) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
const cspHeader = `
default-src 'self';
script-src 'self' ${isProd ? '' : "'unsafe-eval'"} 'nonce-${nonce}' ${authUrl} 'strict-dynamic';
`;
Refused to connect to '<URL>'
because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback
Error message:
Refused to connect to '<URL>' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
Refused to connect to 'https://sr-client-cfg.amplitude.com/config?api_key=8750e93cf3cf432b04d4644133f3aa5c&config_keys=analyticsSDK&session_id=1750047771451' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
...
Root cause
'connect-src'
directive is not set.
Solution
Set the 'connect-src'
directive in the Content Security Policy (CSP) headers, and start with a basic value:
connect-src 'self';
Then, inspect the project codebase and monitor error messages in Chrome DevTools to update the connect-src
values accordingly. For example, if the error message is:
Refused to connect to '<URL>' because it violates the following Content Security Policy directive: "connect-src 'self'".
Refused to connect to 'https://api2.amplitude.com/2/httpapi' because it violates the following Content Security Policy directive: "connect-src 'self'".
...
As shown in the image:
We should add the URL https://api2.amplitude.com/2/httpapi
to the connect-src
directive:
connect-src 'self' https://api2.amplitude.com/2/httpapi;
Additionally, for URLs with dynamic query parameters (e.g. https://sr-client-cfg.amplitude.com/config?api_key=...&session_id=...
), extract only the protocol and host, then add it to connect-src
. The updated directive would look like:
connect-src 'self' https://api2.amplitude.com/2/httpapi https://sr-client-cfg.amplitude.com;
According to Content-Security-Policy: connect-src directive
The following APIs are controlled by this directive:
- The
ping
attribute in<a>
elementsfetch()
fetchLater()
ExperimentalXMLHttpRequest
WebSocket
EventSource
Navigator.sendBeacon()
To ensure compliance, review the codebase for any usage of these APIs that make external network requests. If any requests are made to URLs not currently listed in the connect-src
directive, update the CSP header to include those origins accordingly.
Top comments (0)