Skip to content

Account Enumeration and Arbitrary Password Reset in Forgot Password Functionality #26

Description

@duckpigdog

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.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions