Skip to content

Commit 12ce969

Browse files
committedMar 25, 2024
Make CSP more strict
1 parent 4c4f54d commit 12ce969

File tree

2 files changed

+61
-27
lines changed

2 files changed

+61
-27
lines changed
 

‎next.config.mjs

-27
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,5 @@
1-
const cspHeader = `
2-
default-src 'self';
3-
script-src 'self' 'unsafe-eval' 'unsafe-inline';
4-
style-src 'self' 'unsafe-inline';
5-
img-src 'self' blob: data:;
6-
font-src 'self';
7-
object-src 'none';
8-
base-uri 'self';
9-
form-action 'self';
10-
frame-ancestors 'none';
11-
block-all-mixed-content;
12-
upgrade-insecure-requests;
13-
`
14-
151
/** @type {import('next').NextConfig} */
162
const nextConfig = {
17-
async headers() {
18-
return [
19-
{
20-
source: '/(.*)',
21-
headers: [
22-
{
23-
key: 'Content-Security-Policy',
24-
value: cspHeader.replace(/\n/g, ''),
25-
},
26-
],
27-
},
28-
]
29-
},
303
images: {
314
formats: [
325
// 'image/avif', //disabled because the conversion is seriously slow

‎src/middleware.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
3+
export const middleware = (request: NextRequest) => {
4+
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
5+
const cspHeader = `
6+
default-src 'self';
7+
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
8+
style-src 'self' 'nonce-${nonce}';
9+
img-src 'self' blob: data:;
10+
font-src 'self';
11+
object-src 'none';
12+
base-uri 'self';
13+
form-action 'self';
14+
frame-ancestors 'none';
15+
block-all-mixed-content;
16+
upgrade-insecure-requests;
17+
`;
18+
// Replace newline characters and spaces
19+
const contentSecurityPolicyHeaderValue = cspHeader
20+
.replace(/\s{2,}/g, " ")
21+
.trim();
22+
23+
const requestHeaders = new Headers(request.headers);
24+
requestHeaders.set("x-nonce", nonce);
25+
26+
requestHeaders.set(
27+
"Content-Security-Policy",
28+
contentSecurityPolicyHeaderValue,
29+
);
30+
31+
const response = NextResponse.next({
32+
request: {
33+
headers: requestHeaders,
34+
},
35+
});
36+
response.headers.set(
37+
"Content-Security-Policy",
38+
contentSecurityPolicyHeaderValue,
39+
);
40+
41+
return response;
42+
};
43+
44+
export const config = {
45+
matcher: [
46+
/*
47+
* Match all request paths except for the ones starting with:
48+
* - api (API routes)
49+
* - _next/static (static files)
50+
* - _next/image (image optimization files)
51+
* - favicon.ico (favicon file)
52+
*/
53+
{
54+
source: "/((?!api|_next/static|_next/image|favicon.ico).*)",
55+
missing: [
56+
{ type: "header", key: "next-router-prefetch" },
57+
{ type: "header", key: "purpose", value: "prefetch" },
58+
],
59+
},
60+
],
61+
};

0 commit comments

Comments
 (0)