Apply strict rate limits to sensitive auth endpoints.
Account deletion, key enrollment, and credential management use a separate 30/15min limiter so they are not left at 300/min while login and sync routes stay independent. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+26
-3
@@ -45,7 +45,7 @@ export function createApp(): express.Express {
|
|||||||
app.use(cookieParser())
|
app.use(cookieParser())
|
||||||
app.use(express.json({ limit: '50mb' }))
|
app.use(express.json({ limit: '50mb' }))
|
||||||
|
|
||||||
/** Passkey login/register only — not person-pool, profile, etc. */
|
/** WebAuthn login/register/session — strict per IP; excludes high-volume sync routes. */
|
||||||
const authFlowPaths = new Set([
|
const authFlowPaths = new Set([
|
||||||
'/register-options',
|
'/register-options',
|
||||||
'/register-verify',
|
'/register-verify',
|
||||||
@@ -57,13 +57,33 @@ export function createApp(): express.Express {
|
|||||||
'/session'
|
'/session'
|
||||||
])
|
])
|
||||||
|
|
||||||
const authLimiter = rateLimit({
|
/** Account/key/credential mutations — also strict; separate bucket from login flow. */
|
||||||
|
const sensitiveAuthExactPaths = new Set([
|
||||||
|
'/delete-account',
|
||||||
|
'/enroll-prf',
|
||||||
|
'/rotate-recovery',
|
||||||
|
'/add-credential-options',
|
||||||
|
'/add-credential-verify'
|
||||||
|
])
|
||||||
|
|
||||||
|
function isSensitiveAuthPath(path: string): boolean {
|
||||||
|
return sensitiveAuthExactPaths.has(path) || path.startsWith('/credentials/')
|
||||||
|
}
|
||||||
|
|
||||||
|
const authFlowLimiter = rateLimit({
|
||||||
windowMs: 15 * 60 * 1000,
|
windowMs: 15 * 60 * 1000,
|
||||||
max: 60,
|
max: 60,
|
||||||
standardHeaders: true,
|
standardHeaders: true,
|
||||||
legacyHeaders: false
|
legacyHeaders: false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const sensitiveAuthLimiter = rateLimit({
|
||||||
|
windowMs: 15 * 60 * 1000,
|
||||||
|
max: 30,
|
||||||
|
standardHeaders: true,
|
||||||
|
legacyHeaders: false
|
||||||
|
})
|
||||||
|
|
||||||
const apiLimiter = rateLimit({
|
const apiLimiter = rateLimit({
|
||||||
windowMs: 1 * 60 * 1000,
|
windowMs: 1 * 60 * 1000,
|
||||||
max: 300,
|
max: 300,
|
||||||
@@ -80,7 +100,10 @@ export function createApp(): express.Express {
|
|||||||
|
|
||||||
app.use('/api/auth', (req, res, next) => {
|
app.use('/api/auth', (req, res, next) => {
|
||||||
if (authFlowPaths.has(req.path)) {
|
if (authFlowPaths.has(req.path)) {
|
||||||
return authLimiter(req, res, next)
|
return authFlowLimiter(req, res, next)
|
||||||
|
}
|
||||||
|
if (isSensitiveAuthPath(req.path)) {
|
||||||
|
return sensitiveAuthLimiter(req, res, next)
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user