61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
// @Docs https://content-security-policy.com/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
export class CSP {
|
|
private readonly request: any
|
|
private readonly on: boolean
|
|
private readonly request_headers?: Headers
|
|
private readonly csp_with_nonce?: string
|
|
private next_response?: NextResponse
|
|
|
|
constructor (request: any, on?: boolean) {
|
|
this.request = request
|
|
this.on = on ?? true
|
|
|
|
if (this.on) {
|
|
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
|
|
this.csp_with_nonce = CSP.contentSecurityPolicyHeaderValue(nonce)
|
|
this.request_headers = new Headers(this.request.headers)
|
|
this.request_headers.set('x-nonce', nonce)
|
|
this.request_headers.set('x-xxx', '123')
|
|
this.request_headers.set('Content-Security-Policy', this.csp_with_nonce)
|
|
}
|
|
}
|
|
|
|
private static contentSecurityPolicyHeaderValue (nonce: string): string {
|
|
//style-src 'self' 'nonce-${nonce}';
|
|
return `
|
|
default-src 'self';
|
|
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
|
|
style-src 'self' 'unsafe-inline';
|
|
img-src 'self' blob: data: avatars.githubusercontent.com *.googleusercontent.com;
|
|
connect-src 'self';
|
|
font-src 'self';
|
|
object-src 'none';
|
|
base-uri 'self';
|
|
form-action 'self';
|
|
frame-ancestors 'none';
|
|
upgrade-insecure-requests`.replace(/\s{2,}/g, ' ').trim()
|
|
}
|
|
|
|
next (middleware?: (request: NextRequest) => NextResponse<unknown>): NextResponse<unknown> {
|
|
if (!this.on) {
|
|
return middleware ? middleware(this.request) : NextResponse.next()
|
|
}
|
|
|
|
if (middleware) {
|
|
const reqNext = new NextRequest(this.request, { headers: this.request_headers })
|
|
this.next_response = middleware(reqNext)
|
|
} else {
|
|
this.next_response = NextResponse.next({
|
|
request: { headers: this.request_headers },
|
|
})
|
|
}
|
|
|
|
this.next_response.headers.set('Content-Security-Policy', this.csp_with_nonce as string)
|
|
|
|
return this.next_response
|
|
}
|
|
}
|