@@ -5,6 +5,56 @@ import type { NextRequest } from 'next/server';
5
5
6
6
import env from './lib/env' ;
7
7
8
+ // Constants for security headers
9
+ const SECURITY_HEADERS = {
10
+ 'Referrer-Policy' : 'strict-origin-when-cross-origin' ,
11
+ 'Permissions-Policy' : 'geolocation=(), microphone=()' ,
12
+ 'Cross-Origin-Embedder-Policy' : 'require-corp' ,
13
+ 'Cross-Origin-Opener-Policy' : 'same-origin' ,
14
+ 'Cross-Origin-Resource-Policy' : 'same-site' ,
15
+ } as const ;
16
+
17
+ // Generate CSP
18
+ const generateCSP = ( ) : string => {
19
+ const policies = {
20
+ 'default-src' : [ "'self'" ] ,
21
+ 'img-src' : [
22
+ "'self'" ,
23
+ 'boxyhq.com' ,
24
+ '*.boxyhq.com' ,
25
+ '*.dicebear.com' ,
26
+ 'data:' ,
27
+ ] ,
28
+ 'script-src' : [
29
+ "'self'" ,
30
+ "'unsafe-inline'" ,
31
+ "'unsafe-eval'" ,
32
+ '*.gstatic.com' ,
33
+ '*.google.com' ,
34
+ ] ,
35
+ 'style-src' : [ "'self'" , "'unsafe-inline'" ] ,
36
+ 'connect-src' : [
37
+ "'self'" ,
38
+ '*.google.com' ,
39
+ '*.gstatic.com' ,
40
+ 'boxyhq.com' ,
41
+ '*.ingest.sentry.io' ,
42
+ '*.mixpanel.com' ,
43
+ ] ,
44
+ 'frame-src' : [ "'self'" , '*.google.com' , '*.gstatic.com' ] ,
45
+ 'font-src' : [ "'self'" ] ,
46
+ 'object-src' : [ "'none'" ] ,
47
+ 'base-uri' : [ "'self'" ] ,
48
+ 'form-action' : [ "'self'" ] ,
49
+ 'frame-ancestors' : [ "'none'" ] ,
50
+ } ;
51
+
52
+ return Object . entries ( policies )
53
+ . map ( ( [ key , values ] ) => `${ key } ${ values . join ( ' ' ) } ` )
54
+ . concat ( [ 'upgrade-insecure-requests' ] )
55
+ . join ( '; ' ) ;
56
+ } ;
57
+
8
58
// Add routes that don't require authentication
9
59
const unAuthenticatedRoutes = [
10
60
'/api/hello' ,
@@ -63,8 +113,25 @@ export default async function middleware(req: NextRequest) {
63
113
}
64
114
}
65
115
116
+ const requestHeaders = new Headers ( req . headers ) ;
117
+ const csp = generateCSP ( ) ;
118
+
119
+ requestHeaders . set ( 'Content-Security-Policy' , csp ) ;
120
+
121
+ const response = NextResponse . next ( {
122
+ request : { headers : requestHeaders } ,
123
+ } ) ;
124
+
125
+ if ( env . securityHeadersEnabled ) {
126
+ // Set security headers
127
+ response . headers . set ( 'Content-Security-Policy' , csp ) ;
128
+ Object . entries ( SECURITY_HEADERS ) . forEach ( ( [ key , value ] ) => {
129
+ response . headers . set ( key , value ) ;
130
+ } ) ;
131
+ }
132
+
66
133
// All good, let the request through
67
- return NextResponse . next ( ) ;
134
+ return response ;
68
135
}
69
136
70
137
export const config = {
0 commit comments