Rate-limit /reauth endpoint: 5 attempts per 15min

This commit is contained in:
2026-05-09 22:17:03 +01:00
parent ca7555a603
commit 6915ce518b
+4 -2
View File
@@ -511,18 +511,20 @@ try {
case ($path === '/reauth' && $method === 'POST'):
$auth = authenticate($db);
requireCSRF($db, $auth['userId']);
if (checkRateLimit($db) >= 5) { http_response_code(429); echo json_encode(['error'=>'Too many attempts. Try again later.']); break; }
$p = $input['masterPassword'] ?? '';
$st = $db->prepare('SELECT * FROM users WHERE id=:uid');
$st->bindValue(':uid', $auth['userId'], SQLITE3_INTEGER);
$user = $st->execute()->fetchArray(SQLITE3_ASSOC);
if (!$user) { http_response_code(401); echo json_encode(['error'=>'User not found']); break; }
if (!$user) { recordAttempt($db); http_response_code(401); echo json_encode(['error'=>'User not found']); break; }
$algo = $user['hash_algo'] ?? 'pbkdf2';
if ($algo === 'bcrypt') {
$valid = password_verify($p, $user['password_hash']);
} else {
$valid = hash_equals($user['password_hash'], hash_pbkdf2('sha256', $p, $user['salt'], 100000));
}
if (!$valid) { logAudit($db, $auth['userId'], 'failed_reauth'); http_response_code(401); echo json_encode(['error'=>'Invalid password']); break; }
if (!$valid) { recordAttempt($db); logAudit($db, $auth['userId'], 'failed_reauth'); http_response_code(401); echo json_encode(['error'=>'Invalid password']); break; }
clearAttempts($db);
logAudit($db, $auth['userId'], 'reauth');
echo json_encode(['message'=>'OK']);
break;