AOSSIE-Org / AOSSIE-Org/DebateAI

[BUG]: Password reset code never expires — indefinite account-takeover window

Đã đóng
#485 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
bug
Ngôn ngữ chính
TypeScript
Star
84
Fork
198
Merge trung bình
2 ngày 19 giờ
Pull request đã merge (30 ngày)
30

Mô tả

### Bug Description

The password reset flow issues a 6-digit reset code that **never expires**. `ResetPassword` validates only that the code matches — there is no time-based expiry check, and no expiry timestamp is stored when the code is generated.

**`ForgotPassword` (auth.go ~424):** generates the code and stores it with no expiry:
```go
resetCode := utils.GenerateRandomCode(6)
update := bson.M{"$set": bson.M{
"resetPasswordCode": resetCode,
"updatedAt": now, // not an expiry; just a generic timestamp
}}
```

**`ResetPassword` (auth.go ~463):** matches the code and resets immediately — no expiry check:
```go
err := ...FindOne(dbCtx, bson.M{"email": request.Email, "resetPasswordCode": request.Code}).Decode(&user)
if err != nil { /* invalid */ }
// no time check here — proceeds straight to hashing + updating the password
```

**For contrast, the signup OTP flow does enforce expiry** (auth.go ~240):
```go
if time.Since(user.CreatedAt) > 24*time.Hour {
ctx.JSON(400, gin.H{"error": "Verification code expired. Please sign up again."})
return
}
```

The `User` model has `ResetPasswordCode` but no `resetPasswordCodeExpiry` field, so there's nothing to check against.

**Security impact:** a reset code stays valid indefinitely until used. If a reset email is ever exposed later (old/archived email, shared or compromised inbox, mail forwarding, a device the user no longer controls), the code can still reset the password weeks or months on. Reset codes are meant to be short-lived (typically 15–60 minutes) to bound this window. With only 6 digits and no visible rate limiting on the verify endpoint, a never-expiring code raises account-takeover risk further.

### Steps to Reproduce

1. Request a password reset (`/forgotpassword`) for an account — a 6-digit code is emailed and stored.
2. Wait an arbitrarily long time (hours, days, weeks).
3. Submit the reset (`/resetpassword`) with that old code and a new password.
4. Observe the password is reset successfully — the code is still accepted with no expiry.

### Logs and Screenshots

ForgotPassword stores the code with no expiry (auth.go ~424):
"resetPasswordCode": resetCode,
"updatedAt": now,

ResetPassword accepts it with no time check (auth.go ~463):
FindOne(..., bson.M{"email": request.Email, "resetPasswordCode": request.Code})
// → straight to password update, no expiry validation

Signup OTP, by contrast, does check (auth.go ~240):
if time.Since(user.CreatedAt) > 24*time.Hour { /* expired */ }

### Environment Details

- File: backend/controllers/auth.go (ForgotPassword, ResetPassword)
- Model: backend/models/user.go (ResetPasswordCode; no expiry field)
- Backend: Go / MongoDB
- Branch: main
- Suggested fix: add a resetPasswordCodeExpiry timestamp on generation (e.g. now + 30 min) and reject in ResetPassword when time.Now() is past it; clear the code after use (already cleared on success)

### Impact

Medium - Feature works but has issues

### Code of Conduct

- [x] I have joined the [Discord server](https://discord.gg/hjUhu33uAn) and will post updates there
- [x] I have searched existing issues to avoid duplicates

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Start in backend/controllers/auth.go at ForgotPassword and ResetPassword, then inspect backend/models/user.go and the existing signup OTP expiry check around line 240. Verify that reset-code expiry is recorded on generation, expired codes are rejected, and successful resets still clear the code; run the relevant backend authentication tests if available.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
go, mongodb
Lĩnh vực
authentication, backend, databases
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
68/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.