fix(admin-auth): add rate limiting to admin login endpoint
All checks were successful
build-and-release / build (makeup-artists) (push) Successful in 8m13s
build-and-release / build (cron) (push) Successful in 4m39s
build-and-release / build (gateway) (push) Successful in 2m47s
build-and-release / build (employees) (push) Successful in 8m49s
build-and-release / build (fitness-trainers) (push) Successful in 7m42s
build-and-release / build (payments) (push) Successful in 8m6s
build-and-release / build (jobs) (push) Successful in 4m19s
build-and-release / build (catering-services) (push) Successful in 9m29s
build-and-release / build (photographers) (push) Successful in 8m44s
build-and-release / build (customers) (push) Successful in 9m30s
build-and-release / build (tutors) (push) Successful in 7m8s
build-and-release / build (developers) (push) Successful in 9m35s
build-and-release / build (graphic-designers) (push) Successful in 9m33s
build-and-release / build (social-media-managers) (push) Successful in 8m57s
build-and-release / build (leads) (push) Successful in 9m9s
build-and-release / build (ugc-content-creators) (push) Successful in 8m52s
build-and-release / build (video-editors) (push) Successful in 8m14s
build-and-release / build (companies) (push) Successful in 9m58s
build-and-release / build (job-seekers) (push) Successful in 9m55s
build-and-release / build (users) (push) Successful in 10m21s
All checks were successful
build-and-release / build (makeup-artists) (push) Successful in 8m13s
build-and-release / build (cron) (push) Successful in 4m39s
build-and-release / build (gateway) (push) Successful in 2m47s
build-and-release / build (employees) (push) Successful in 8m49s
build-and-release / build (fitness-trainers) (push) Successful in 7m42s
build-and-release / build (payments) (push) Successful in 8m6s
build-and-release / build (jobs) (push) Successful in 4m19s
build-and-release / build (catering-services) (push) Successful in 9m29s
build-and-release / build (photographers) (push) Successful in 8m44s
build-and-release / build (customers) (push) Successful in 9m30s
build-and-release / build (tutors) (push) Successful in 7m8s
build-and-release / build (developers) (push) Successful in 9m35s
build-and-release / build (graphic-designers) (push) Successful in 9m33s
build-and-release / build (social-media-managers) (push) Successful in 8m57s
build-and-release / build (leads) (push) Successful in 9m9s
build-and-release / build (ugc-content-creators) (push) Successful in 8m52s
build-and-release / build (video-editors) (push) Successful in 8m14s
build-and-release / build (companies) (push) Successful in 9m58s
build-and-release / build (job-seekers) (push) Successful in 9m55s
build-and-release / build (users) (push) Successful in 10m21s
The admin/employee login handler had no brute-force protection, unlike the regular user login path. Given these accounts hold internal/ super-admin privileges, add a tighter limit (5 attempts/15min vs 10 for regular users) using the existing sliding-window Redis limiter. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e53098728a
commit
b9133018a5
2 changed files with 12 additions and 1 deletions
|
|
@ -54,7 +54,12 @@ async fn login(
|
|||
Json(payload): Json<LoginPayload>,
|
||||
) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
|
||||
let email = payload.email.to_lowercase();
|
||||
|
||||
let mut redis = state.redis.clone();
|
||||
|
||||
if !cache::rate_limit::check_admin_login(&mut redis, &email).await.unwrap_or(true) {
|
||||
return Err(err(StatusCode::TOO_MANY_REQUESTS, "Too many login attempts. Try again in 15 minutes.", "RATE_LIMITED"));
|
||||
}
|
||||
|
||||
let employee = EmployeeRepository::get_by_email(&state.pool, &email)
|
||||
.await
|
||||
.map_err(|_| err(StatusCode::INTERNAL_SERVER_ERROR, "DB error", "DB_ERROR"))?
|
||||
|
|
|
|||
6
crates/cache/src/rate_limit.rs
vendored
6
crates/cache/src/rate_limit.rs
vendored
|
|
@ -41,6 +41,12 @@ pub async fn check_login(redis: &mut RedisPool, email: &str) -> Result<bool, red
|
|||
check(redis, "login", email, 10, 900).await
|
||||
}
|
||||
|
||||
/// Admin/employee login: max 5 attempts per 15 min per email (tighter than regular
|
||||
/// user login because these accounts hold internal/super-admin privileges).
|
||||
pub async fn check_admin_login(redis: &mut RedisPool, email: &str) -> Result<bool, redis::RedisError> {
|
||||
check(redis, "admin_login", email, 5, 900).await
|
||||
}
|
||||
|
||||
/// Lead request: max 5 per hour per professional
|
||||
pub async fn check_lead(redis: &mut RedisPool, professional_id: &str) -> Result<bool, redis::RedisError> {
|
||||
check(redis, "lead", professional_id, 5, 3_600).await
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue