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
pingattribute in<a>elementsfetch()fetchLater()ExperimentalXMLHttpRequestWebSocketEventSourceNavigator.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)