enhanced security and input validation
This commit is contained in:
41
middleware/security.ts
Normal file
41
middleware/security.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export function securityHeaders(req: NextApiRequest, res: NextApiResponse, next: () => void) {
|
||||
// Set security headers
|
||||
res.setHeader('X-Content-Type-Options', 'nosniff')
|
||||
res.setHeader('X-Frame-Options', 'DENY')
|
||||
res.setHeader('X-XSS-Protection', '1; mode=block')
|
||||
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
|
||||
res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()')
|
||||
|
||||
// Prevent information leakage
|
||||
res.removeHeader('X-Powered-By')
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export function validateContentType(allowedTypes: string[] = ['application/json']) {
|
||||
return (req: NextApiRequest, res: NextApiResponse, next: () => void) => {
|
||||
if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
|
||||
const contentType = req.headers['content-type']
|
||||
|
||||
if (!contentType || !allowedTypes.some(type => contentType.includes(type))) {
|
||||
return res.status(415).json({ error: 'Unsupported Media Type' })
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
export function validateRequestSize(maxSize = 1024 * 1024) { // 1MB default
|
||||
return (req: NextApiRequest, res: NextApiResponse, next: () => void) => {
|
||||
const contentLength = req.headers['content-length']
|
||||
|
||||
if (contentLength && parseInt(contentLength) > maxSize) {
|
||||
return res.status(413).json({ error: 'Request entity too large' })
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user