@@ -8,6 +8,11 @@ import { authRoutes } from "./routes/auth.ts";
88import { logChromiumAvailability } from "./utils/chromium.ts" ;
99import { ensureEnv } from "./utils/env.ts" ;
1010
11+ const SECURE_HEADERS_DISABLED = ( Deno . env . get ( "SECURE_HEADERS_DISABLED" ) || "" ) . toLowerCase ( ) === "true" ;
12+ const HSTS_ENABLED = ( Deno . env . get ( "ENABLE_HSTS" ) || "" ) . toLowerCase ( ) === "true" ;
13+ const CONTENT_SECURITY_POLICY = Deno . env . get ( "CONTENT_SECURITY_POLICY" ) ||
14+ "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; script-src 'none'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; connect-src 'self'" ;
15+
1116const app = new Hono ( ) ;
1217
1318// Check for required credentials in environment
@@ -59,6 +64,39 @@ app.use(
5964 } ) ,
6065) ;
6166
67+ app . use ( "*" , async ( c , next ) => {
68+ await next ( ) ;
69+ if ( SECURE_HEADERS_DISABLED ) return ;
70+ const headers = c . res . headers ;
71+ if ( ! headers . has ( "X-Content-Type-Options" ) ) {
72+ headers . set ( "X-Content-Type-Options" , "nosniff" ) ;
73+ }
74+ if ( ! headers . has ( "X-Frame-Options" ) ) {
75+ headers . set ( "X-Frame-Options" , "DENY" ) ;
76+ }
77+ if ( ! headers . has ( "Referrer-Policy" ) ) {
78+ headers . set ( "Referrer-Policy" , "no-referrer" ) ;
79+ }
80+ if ( ! headers . has ( "Permissions-Policy" ) ) {
81+ headers . set ( "Permissions-Policy" , "accelerometer=(), autoplay=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" ) ;
82+ }
83+ if ( ! headers . has ( "Cross-Origin-Opener-Policy" ) ) {
84+ headers . set ( "Cross-Origin-Opener-Policy" , "same-origin" ) ;
85+ }
86+ if ( ! headers . has ( "Cross-Origin-Resource-Policy" ) ) {
87+ headers . set ( "Cross-Origin-Resource-Policy" , "same-site" ) ;
88+ }
89+ if ( ! headers . has ( "Content-Security-Policy" ) ) {
90+ headers . set ( "Content-Security-Policy" , CONTENT_SECURITY_POLICY ) ;
91+ }
92+ if ( HSTS_ENABLED && ! headers . has ( "Strict-Transport-Security" ) ) {
93+ const proto = c . req . header ( "x-forwarded-proto" ) ?. toLowerCase ( ) || ( c . req . url . startsWith ( "https://" ) ? "https" : "http" ) ;
94+ if ( proto === "https" ) {
95+ headers . set ( "Strict-Transport-Security" , "max-age=31536000; includeSubDomains" ) ;
96+ }
97+ }
98+ } ) ;
99+
62100// Routes
63101app . route ( "/api/v1" , adminRoutes ) ;
64102app . route ( "/api/v1" , publicRoutes ) ;
0 commit comments