Test case 18 / 19PASS

OTP Bruteforce Protection - Authentication - Password Reset (Per-Session Lockout)

Lab environment — not a production system

Screenshots and raw traffic are not translated; text within them may be in another language.

crAPI/Evidence/[PASS] OTP Bruteforce Protection - Authentication - Password Reset (Per-Session Lockout)

01 — Notes

Test notes

Vulnerability

[PASS] OTP Bruteforce Protection - Authentication - Password Reset (Per-Session Lockout)

Description

Tested OTP brute force within a single OTP session without requesting a new OTP.

Impact

No impact on this path: lockout triggers after 9 attempts (HTTP 503), so per-session brute force fails.

CWE

CWE-307: Improper Restriction of Excessive Authentication Attempts (per-session control PRESENT)

OWASP

API2:2023 - Broken Authentication (negative test - per-session path)

Scenario

Normal: one OTP attempt -> Invalid. Exploitation: brute force -> lockout 503 after 9 attempts. PASS (per-session control holds). The bypass is covered in [FAIL].

Endpoint

POST http://127.0.0.1:8888/identity/api/auth/v3/check-otp

Affected feature

Password Reset via OTP (crapi-identity)

Remediation

Make the lockout PERSISTENT per account so it cannot be reset by a new OTP request (see the related [FAIL] finding).

Proof of concept

1) (Screenshot 1) NORMAL: POST v3/check-otp with one wrong attempt -> Invalid OTP. 2) (Screenshot 2) EXPLOITATION: repeat attempts; on the 10th attempt the lockout triggers -> 503 "You've exceeded the number of attempts" (per-session control holds).
View source note (English)
Vulnerability: [PASS] OTP Bruteforce Protection - Authentication - Password Reset (Per-Session Lockout)

Description:
Tested OTP brute force within a single OTP session without requesting a new OTP.

Impact:
No impact on this path: lockout triggers after 9 attempts (HTTP 503), so per-session brute force fails.

CWE:
CWE-307: Improper Restriction of Excessive Authentication Attempts (per-session control PRESENT)

OWASP:
API2:2023 - Broken Authentication (negative test - per-session path)

Scenario:
Normal: one OTP attempt -> Invalid. Exploitation: brute force -> lockout 503 after 9 attempts. PASS (per-session control holds). The bypass is covered in [FAIL].

Endpoint:
POST http://127.0.0.1:8888/identity/api/auth/v3/check-otp

Affected Feature:
Password Reset via OTP (crapi-identity)

Remediation:
Make the lockout PERSISTENT per account so it cannot be reset by a new OTP request (see the related [FAIL] finding).

POC:
1) (Screenshot 1) NORMAL: POST v3/check-otp with one wrong attempt -> Invalid OTP.
2) (Screenshot 2) EXPLOITATION: repeat attempts; on the 10th attempt the lockout triggers -> 503 "You've exceeded the number of attempts" (per-session control holds).

02 — Screenshots

Screenshots (2)

01 / Normal: one OTP attempt

Normal flow: one incorrect OTP attempt returns Invalid OTP.

02 / Result: lockout after 9 OTP attempts (PASS)

Result (PASS): brute-forcing the OTP within one session triggers a lockout after 9 attempts (503 exceeded attempts). The lockout held in this test, but forget-password can bypass it; see [FAIL].

03 — Requests and responses

HTTP captures

Some credential values are masked in this public HTML view. This does not mean every sensitive value or linked file has been redacted.

CAPTURE 01 / 1Normal: one OTP attempt
HTTP request
POST /identity/api/auth/v3/check-otp HTTP/1.1
Host: 127.0.0.1:8888
Content-Type: application/json

{"email":"[REDACTED-EMAIL]","otp":"9001","password":"[REDACTED-LAB-VALUE]"}
HTTP response
HTTP/1.1 500
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 58

{
  "message": "Invalid OTP! Please try again..",
  "status": 500
}

Normal flow: one incorrect OTP attempt returns Invalid OTP.

CAPTURE 02 / 2Result: lockout after 9 OTP attempts (PASS)
HTTP request
POST /identity/api/auth/v3/check-otp HTTP/1.1
Host: 127.0.0.1:8888
Content-Type: application/json

{"email":"[REDACTED-EMAIL]","otp":"<diulang>","password":"[REDACTED-LAB-VALUE]"}
HTTP response
HTTP/1.1 503
Server: openresty/1.27.1.2
Content-Type: application/json
Content-Length: 66

{
  "message": "You've exceeded the number of attempts.",
  "status": 503
}

Result (PASS): brute-forcing the OTP within one session triggers a lockout after 9 attempts (503 exceeded attempts). The lockout held in this test, but forget-password can bypass it; see [FAIL].