fix: return 403, not 500, for disallowed CORS origins
The cors() origin callback rejected disallowed origins by calling callback(new Error(...)), which Express routes to the generic error handler - previously hardcoded to always respond 500 and log "Unhandled error". A rejected origin is expected, routine traffic (bots, scanners, or a deliberate CORS test), not a server fault, and was being reported and logged as one. The request was already being correctly rejected either way (no data processed, no email sent) - this only fixes the status code and log noise, not a security gap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
f50442a5c8
commit
45ff50e34c
|
|
@ -35,7 +35,12 @@ app.use(
|
||||||
// Same-origin and curl send no Origin header at all.
|
// Same-origin and curl send no Origin header at all.
|
||||||
if (!origin) return callback(null, true)
|
if (!origin) return callback(null, true)
|
||||||
if (allowedOrigins.includes(origin)) return callback(null, true)
|
if (allowedOrigins.includes(origin)) return callback(null, true)
|
||||||
callback(new Error('Origin not allowed'))
|
const error = new Error('Origin not allowed')
|
||||||
|
// Read by the error handler below - a rejected origin is expected,
|
||||||
|
// routine traffic (bots, scanners, this exact curl test), not a
|
||||||
|
// server fault, and should neither look like one nor be logged as one.
|
||||||
|
error.status = 403
|
||||||
|
callback(error)
|
||||||
},
|
},
|
||||||
methods: ['POST'],
|
methods: ['POST'],
|
||||||
allowedHeaders: ['Content-Type'],
|
allowedHeaders: ['Content-Type'],
|
||||||
|
|
@ -51,8 +56,15 @@ app.use('/api/audit-request', auditRouter)
|
||||||
|
|
||||||
// Keep internals out of the response body.
|
// Keep internals out of the response body.
|
||||||
app.use((error, _req, res, _next) => {
|
app.use((error, _req, res, _next) => {
|
||||||
|
const status = error.status ?? 500
|
||||||
|
if (status >= 500) {
|
||||||
console.error('Unhandled error:', error.message)
|
console.error('Unhandled error:', error.message)
|
||||||
res.status(500).json({ success: false, message: 'Internal server error.' })
|
res.status(500).json({ success: false, message: 'Internal server error.' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Expected rejections (e.g. disallowed CORS origin) - not a server fault,
|
||||||
|
// so no error-level log line and no generic message.
|
||||||
|
res.status(status).json({ success: false, message: error.message })
|
||||||
})
|
})
|
||||||
|
|
||||||
const port = Number(env('PORT', '3001'))
|
const port = Number(env('PORT', '3001'))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue