Skip to content

Commit 36f8336

Browse files
committed
feat(middleware): add security headers middleware 🛡️
- Add security headers middleware export in index - Add SecurityHeaders middleware implementation - Update documentation config for security headers navigation - Update README with security headers middleware reference
1 parent a4c8db8 commit 36f8336

6 files changed

Lines changed: 483 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Follow our [installing guide](https://docs-deserve.neabyte.com/en/getting-starte
3535
- [Basic Auth](https://docs-deserve.neabyte.com/en/middleware/basic-auth) - HTTP Basic Authentication
3636
- [Body Limit](https://docs-deserve.neabyte.com/en/middleware/body-limit) - Enforce maximum request body size
3737
- [CORS](https://docs-deserve.neabyte.com/en/middleware/cors) - Cross-origin request handling
38+
- [Security Headers](https://docs-deserve.neabyte.com/en/middleware/security-headers) - Set HTTP security headers to protect your application
3839
- [WebSocket](https://docs-deserve.neabyte.com/en/middleware/websocket) - Real-time bidirectional communication
3940

4041
- **Response Utilities**

docs/.vitepress/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export default withMermaid(
9999
{ text: '🚧 Basic Auth', link: '/en/middleware/basic-auth' },
100100
{ text: '🚧 Body Limit', link: '/en/middleware/body-limit' },
101101
{ text: 'CORS', link: '/en/middleware/cors' },
102+
{ text: '🚧 Security Headers', link: '/en/middleware/security-headers' },
102103
{ text: 'WebSocket', link: '/en/middleware/websocket' }
103104
]
104105
},
@@ -169,6 +170,7 @@ export default withMermaid(
169170
{ text: '🚧 Basic Auth', link: '/en/middleware/basic-auth' },
170171
{ text: '🚧 Body Limit', link: '/en/middleware/body-limit' },
171172
{ text: 'CORS', link: '/en/middleware/cors' },
173+
{ text: '🚧 Security Headers', link: '/en/middleware/security-headers' },
172174
{ text: 'WebSocket', link: '/en/middleware/websocket' }
173175
]
174176
},
@@ -279,6 +281,7 @@ export default withMermaid(
279281
{ text: '🚧 Basic Auth', link: '/id/middleware/basic-auth' },
280282
{ text: '🚧 Body Limit', link: '/id/middleware/body-limit' },
281283
{ text: 'CORS', link: '/id/middleware/cors' },
284+
{ text: '🚧 Security Headers', link: '/id/middleware/security-headers' },
282285
{ text: 'WebSocket', link: '/id/middleware/websocket' }
283286
]
284287
},
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# Security Headers Middleware
2+
3+
> [!WARNING] This feature is available in the development version but not yet released.
4+
5+
> **Reference**: [OWASP Secure Headers Project](https://owasp.org/www-project-secure-headers/)
6+
7+
Security Headers middleware sets HTTP security headers to protect your application from common vulnerabilities like clickjacking, MIME type sniffing, and XSS attacks.
8+
9+
## Basic Usage
10+
11+
Apply security headers middleware using Deserve's built-in middleware:
12+
13+
```typescript
14+
import { Router, Mware } from '@neabyte/deserve'
15+
16+
const router = new Router()
17+
18+
router.use(Mware.securityHeaders({
19+
xContentTypeOptions: 'nosniff',
20+
xFrameOptions: 'DENY',
21+
referrerPolicy: 'no-referrer'
22+
}))
23+
24+
await router.serve(8000)
25+
```
26+
27+
## Route-Specific Security Headers
28+
29+
Apply different security headers to specific routes:
30+
31+
```typescript
32+
// Strict headers for admin routes
33+
router.use('/admin', Mware.securityHeaders({
34+
xContentTypeOptions: 'nosniff',
35+
xFrameOptions: 'DENY',
36+
referrerPolicy: 'no-referrer',
37+
strictTransportSecurity: 'max-age=31536000; includeSubDomains'
38+
}))
39+
40+
// Less strict for public routes
41+
router.use('/api/public', Mware.securityHeaders({
42+
xContentTypeOptions: 'nosniff',
43+
xFrameOptions: 'SAMEORIGIN'
44+
}))
45+
```
46+
47+
## Configuration Options
48+
49+
All headers are optional. Set each header option to a string value to enable it, `false` to disable it explicitly, or leave it `undefined` to skip entirely.
50+
51+
### `contentSecurityPolicy`
52+
53+
Content Security Policy (CSP) to control resource loading:
54+
55+
```typescript
56+
contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'"
57+
```
58+
59+
### `crossOriginEmbedderPolicy`
60+
61+
Cross-Origin Embedder Policy (COEP):
62+
63+
```typescript
64+
crossOriginEmbedderPolicy: 'require-corp' // or 'unsafe-none', 'credentialless'
65+
```
66+
67+
### `crossOriginOpenerPolicy`
68+
69+
Cross-Origin Opener Policy (COOP):
70+
71+
```typescript
72+
crossOriginOpenerPolicy: 'same-origin' // or 'same-origin-allow-popups', 'unsafe-none'
73+
```
74+
75+
### `crossOriginResourcePolicy`
76+
77+
Cross-Origin Resource Policy (CORP):
78+
79+
```typescript
80+
crossOriginResourcePolicy: 'same-origin' // or 'same-site', 'cross-origin'
81+
```
82+
83+
### `originAgentCluster`
84+
85+
Origin Agent Cluster isolation:
86+
87+
```typescript
88+
originAgentCluster: '?1'
89+
```
90+
91+
### `referrerPolicy`
92+
93+
Referrer Policy to control referrer information:
94+
95+
```typescript
96+
referrerPolicy: 'no-referrer' // or 'strict-origin-when-cross-origin', etc.
97+
```
98+
99+
### `strictTransportSecurity`
100+
101+
HTTP Strict Transport Security (HSTS):
102+
103+
```typescript
104+
strictTransportSecurity: 'max-age=31536000; includeSubDomains'
105+
```
106+
107+
### `xContentTypeOptions`
108+
109+
Prevents MIME type sniffing:
110+
111+
```typescript
112+
xContentTypeOptions: 'nosniff'
113+
```
114+
115+
### `xDnsPrefetchControl`
116+
117+
Controls DNS prefetching:
118+
119+
```typescript
120+
xDnsPrefetchControl: 'off' // or 'on'
121+
```
122+
123+
### `xDownloadOptions`
124+
125+
Controls file download options:
126+
127+
```typescript
128+
xDownloadOptions: 'noopen'
129+
```
130+
131+
### `xFrameOptions`
132+
133+
Prevents clickjacking attacks:
134+
135+
```typescript
136+
xFrameOptions: 'DENY' // or 'SAMEORIGIN', 'ALLOW-FROM uri'
137+
```
138+
139+
### `xPermittedCrossDomainPolicies`
140+
141+
Cross-domain policy for Flash:
142+
143+
```typescript
144+
xPermittedCrossDomainPolicies: 'none' // or 'master-only', 'all'
145+
```
146+
147+
### `xPoweredBy`
148+
149+
Remove or customize X-Powered-By header:
150+
151+
```typescript
152+
xPoweredBy: false // Remove header
153+
xPoweredBy: 'Custom' // Set custom value
154+
```
155+
156+
## Complete Example
157+
158+
```typescript
159+
import { Router, Mware } from '@neabyte/deserve'
160+
161+
const router = new Router({ routesDir: './routes' })
162+
163+
router.use(Mware.securityHeaders({
164+
xContentTypeOptions: 'nosniff',
165+
xFrameOptions: 'DENY',
166+
referrerPolicy: 'no-referrer',
167+
xDnsPrefetchControl: 'off',
168+
strictTransportSecurity: 'max-age=31536000; includeSubDomains',
169+
contentSecurityPolicy: "default-src 'self'",
170+
crossOriginOpenerPolicy: 'same-origin',
171+
crossOriginResourcePolicy: 'same-origin'
172+
}))
173+
174+
await router.serve(8000)
175+
```
176+
177+
## Important Notes
178+
179+
- **All headers optional**: Headers are only set if you explicitly provide values
180+
- **Set to `false`**: Explicitly disable a header that might be set elsewhere
181+
- **Undefined**: Skip setting the header entirely
182+
- **X-Powered-By**: Set to `false` to remove, string to customize
183+
- **HSTS**: Only use `strictTransportSecurity` on HTTPS servers
184+
- **CSP**: Content Security Policy can be complex - test thoroughly

0 commit comments

Comments
 (0)