40 lines
1.3 KiB
TypeScript
40 lines
1.3 KiB
TypeScript
import app from '@adonisjs/core/services/app'
|
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
import type { NextFn } from '@adonisjs/core/types/http'
|
|
|
|
/**
|
|
* Only same-origin resources. Angular puts the component styles in
|
|
* <style> tags, hence "unsafe-inline" for styles (not for scripts).
|
|
*/
|
|
const CONTENT_SECURITY_POLICY = [
|
|
"default-src 'self'",
|
|
"script-src 'self'",
|
|
"style-src 'self' 'unsafe-inline'",
|
|
"img-src 'self' data:",
|
|
"font-src 'self'",
|
|
"connect-src 'self'",
|
|
"object-src 'none'",
|
|
"base-uri 'self'",
|
|
"form-action 'self'",
|
|
"frame-ancestors 'none'",
|
|
].join('; ')
|
|
|
|
/**
|
|
* Sets the security headers on every response, including the static
|
|
* files served before the router (which shield does not cover).
|
|
*/
|
|
export default class SecurityHeadersMiddleware {
|
|
handle({ response }: HttpContext, next: NextFn) {
|
|
response.header('Content-Security-Policy', CONTENT_SECURITY_POLICY)
|
|
response.header('X-Frame-Options', 'DENY')
|
|
response.header('X-Content-Type-Options', 'nosniff')
|
|
response.header('Referrer-Policy', 'no-referrer')
|
|
response.header('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
|
|
response.header('Cross-Origin-Opener-Policy', 'same-origin')
|
|
if (app.inProduction) {
|
|
response.header('Strict-Transport-Security', 'max-age=15552000')
|
|
}
|
|
return next()
|
|
}
|
|
}
|