Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions packages/core/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import { getCoreVersion } from './utils/version'
import { bootstrapMiddleware } from './middleware/bootstrap'
import { metricsMiddleware } from './middleware/metrics'
import { securityHeadersMiddleware } from './middleware/security-headers'
import { createDatabaseToolsAdminRoutes } from './plugins/core-plugins/database-tools-plugin/admin-routes'
import { createSeedDataAdminRoutes } from './plugins/core-plugins/seed-data-plugin/admin-routes'
import { emailPlugin } from './plugins/core-plugins/email-plugin'
Expand Down Expand Up @@ -164,10 +165,7 @@ export function createSonicJSApp(config: SonicJSConfig = {}): SonicJSApp {
})

// Security middleware
app.use('*', async (_c, next) => {
// Security headers, CORS, etc.
await next()
})
app.use('*', securityHeadersMiddleware())

// Custom middleware - after auth
if (config.middleware?.afterAuth) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/middleware/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const securityLoggingMiddleware: any = () => async (_c: any, next: any) =
export const performanceLoggingMiddleware: any = () => async (_c: any, next: any) => await next()
export const cacheHeaders: any = () => async (_c: any, next: any) => await next()
export const compressionMiddleware: any = async (_c: any, next: any) => await next()
export const securityHeaders: any = () => async (_c: any, next: any) => await next()
export { securityHeadersMiddleware as securityHeaders } from './security-headers'

// Other stubs
export const PermissionManager: any = {}
Expand Down
23 changes: 23 additions & 0 deletions packages/core/src/middleware/security-headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Context, Next } from 'hono'

/**
* Security headers middleware.
* Sets standard security headers on every response.
* Skips HSTS in development to avoid local dev issues.
*/
export const securityHeadersMiddleware = () => {
return async (c: Context, next: Next) => {
await next()

c.header('X-Content-Type-Options', 'nosniff')
c.header('X-Frame-Options', 'SAMEORIGIN')
c.header('Referrer-Policy', 'strict-origin-when-cross-origin')
c.header('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')

// Only set HSTS in non-development environments
const environment = (c.env as any)?.ENVIRONMENT
if (environment !== 'development') {
c.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')
}
}
}