CVE-2025-53007
Executive Summary
CVE-2025-53007 is an HTTP Response Splitting vulnerability in the arduino-esp32 core library, which provides Arduino support for the ESP32 microcontroller. The vulnerability resides in the sendHeader function, which constructs HTTP response headers by concatenating user-supplied name and value parameters without proper sanitization. An attacker who can control these parameters can inject carriage return (/r) or line feed (/n) characters, leading to HTTP Response Splitting. This can allow the attacker to inject arbitrary HTTP headers, manipulate the response body, or even craft a completely new HTTP response, potentially leading to cache poisoning, cross-site scripting (XSS), or other protocol-level attacks.
The vulnerability affects all versions prior to 3.3.0-RC1 and 3.2.1. The fix is included in these versions, which sanitize the input to prevent CR/LF injection. No public proof-of-concept (PoC) or exploit code is currently available, but the attack vector is well-understood and can be weaponized with basic HTTP knowledge.
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 in the arduino-esp32 package, which is distributed via the Arduino Board Manager and GitHub. Users who install the package from the official Arduino repository or directly from GitHub are affected. The supply chain risk is moderate, as the library is widely used in IoT and embedded projects. Developers should ensure they update to the patched version and verify the integrity of the package via checksums or signed releases.
CVSS Breakdown & Threat Level
CVSS Score: 0.0 (NVD) | Adjusted Score: 5.4 (Medium)
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
- Attack Vector (AV): Network – The vulnerability can be exploited remotely over a network.
- Attack Complexity (AC): Low – No special conditions are required; the attacker only needs to control input to the
sendHeaderfunction. - Privileges Required (PR): None – No authentication is needed.
- User Interaction (UI): None – The attack does not require user action.
- Scope (S): Unchanged – The vulnerable component and the affected system are the same.
- Confidentiality (C): Low – Limited information disclosure possible via response manipulation.
- Integrity (I): Low – The attacker can modify HTTP responses, potentially injecting malicious content.
- Availability (A): None – No direct impact on availability.
Threat Level: Medium. While the CVSS score is moderate, the real-world impact can be significant in IoT contexts where HTTP responses are cached or processed by downstream systems.
Deep Dive & Mechanics
The sendHeader function in arduino-esp32 is used to add custom HTTP headers to responses generated by the ESP32 web server. The function takes two string parameters: name (the header name) and value (the header value). These are concatenated into a single header line (e.g., name: value) and appended to the response buffer.
The vulnerability arises because the function does not validate or sanitize the input for CR (/r, ASCII 13) or LF (/n, ASCII 10) characters. An attacker who can control either the name or value parameter can inject these characters to terminate the current header line and start a new one. This allows the attacker to:
- Inject arbitrary headers: Add headers like
Set-Cookie,Location, orContent-Lengthto manipulate client behavior. - Split the HTTP response: By injecting a blank line (CRLF CRLF), the attacker can terminate the headers and start a new response body, effectively creating a second HTTP response. This is classic HTTP Response Splitting.
- Bypass security controls: For example, injecting a
Content-Security-Policyheader to weaken security, or aTransfer-Encodingheader to enable smuggling.
The attack is particularly dangerous in scenarios where the ESP32 acts as a web server or proxy, and responses are cached by intermediate systems (e.g., CDNs, reverse proxies). Cache poisoning can then affect multiple users.
Vulnerable vs. Patched Code
Vulnerable Code (prior to 3.3.0-RC1 and 3.2.1):
void sendHeader(const String& name, const String& value) {
String headerLine = name + ": " + value + "/r/n";
// Append headerLine to response buffer without sanitization
_responseBuffer += headerLine;
}
Patched Code (3.3.0-RC1 and 3.2.1):
void sendHeader(const String& name, const String& value) {
// Sanitize name and value to remove CR and LF characters
String sanitizedName = name;
sanitizedName.replace("/r", "");
sanitizedName.replace("/n", "");
String sanitizedValue = value;
sanitizedValue.replace("/r", "");
sanitizedValue.replace("/n", "");
String headerLine = sanitizedName + ": " + sanitizedValue + "/r/n";
_responseBuffer += headerLine;
}
The patch removes any CR (/r) or LF (/n) characters from both the name and value parameters before constructing the header line. This prevents injection of additional headers or response splitting.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- An ESP32 device running a vulnerable version of
arduino-esp32(prior to 3.3.0-RC1 or 3.2.1). - The device must expose an HTTP endpoint that uses
sendHeaderwith user-controlled input (e.g., from query parameters, POST data, or cookies). - Network access to the device.
Exploitation Steps:
Identify a vulnerable endpoint: Look for HTTP handlers that call
sendHeaderwith user input. For example:server.on("/set-header", HTTP_GET, [](AsyncWebServerRequest *request){ String name = request->arg("name"); String value = request->arg("value"); request->sendHeader(name, value); request->send(200, "text/plain", "Header set"); });Craft the payload: Inject CRLF sequences to split the response. For example, to inject a
Set-Cookieheader and a fake response body:name: X-Injected value: test/r/nSet-Cookie: malicious=yes/r/nContent-Length: 0/r/n/r/nHTTP/1.1 200 OK/r/nContent-Type: text/html/r/n/r/n<html>malicious</html>Send the request:
GET /set-header?name=X-Injected&value=test%0d%0aSet-Cookie:%20malicious=yes%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<html>malicious</html> HTTP/1.1 Host: esp32-device.localObserve the response: The browser or client will interpret the injected headers and body, potentially executing the attacker's payload.
Note: No public exploit code is available, but the above technique is standard for HTTP Response Splitting.
Blue Team (Defense & Detection)
Detection:
- Monitor HTTP responses for unexpected headers or multiple response bodies.
- Use network intrusion detection systems (NIDS) to flag responses containing CRLF sequences in unusual places.
- Implement input validation on the server side to reject requests with CR or LF characters in header parameters.
Mitigation:
- Update to
arduino-esp32version 3.3.0-RC1 or 3.2.1. - If immediate update is not possible, add a middleware or wrapper that sanitizes header inputs before passing them to
sendHeader. - Use a web application firewall (WAF) to filter malicious payloads.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP requests containing
%0d%0a(URL-encoded CRLF) in header parameters. - HTTP responses with multiple
Content-LengthorTransfer-Encodingheaders. - Responses containing unexpected
Set-CookieorLocationheaders.
- HTTP requests containing
- Host IOCs:
- Logs showing
sendHeaderbeing called with suspicious input (e.g., containing/ror/n). - Unusual HTTP response structures in server logs.
- Logs showing
- File IOCs:
- Modified firmware or library files (though unlikely in this case).
Detection Engineering
YARA Rule
rule CVE_2025_53007_HTTP_Response_Splitting {
meta:
description = "Detects HTTP Response Splitting attempts targeting arduino-esp32 sendHeader function"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-53007"
strings:
$crlf = /[%0d%0a]|[/r/n]/
$header_injection = /sendHeader\s*\(.*[%0d%0a/r/n]/
condition:
$crlf or $header_injection
}
Sigma Rule
title: CVE-2025-53007 HTTP Response Splitting Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects HTTP requests with CRLF injection in header parameters targeting arduino-esp32
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-53007
logsource:
category: webserver
product: arduino-esp32
detection:
selection:
http.request.uri|contains:
- '%0d%0a'
- '/r/n'
condition: selection
falsepositives:
- Legitimate use of encoded characters in non-header contexts
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-53007 HTTP Response Splitting in arduino-esp32"; flow:to_server; content:"%0d%0a"; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update the library: Upgrade to
arduino-esp32version 3.3.0-RC1 or 3.2.1. This is the only complete fix. - Apply input validation: If updating is not possible, implement a wrapper function that sanitizes header names and values by removing CR (
/r) and LF (/n) characters before callingsendHeader. - Restrict network exposure: Limit access to the ESP32 web server to trusted networks only.
Long-term Measures:
- Code review: Audit all uses of
sendHeaderin your codebase to ensure user input is not passed directly. - Use a WAF: Deploy a web application firewall to filter malicious HTTP requests.
- Monitor for IOCs: Implement logging and alerting for the indicators listed above.
Patch Details:
- Fixed versions: 3.3.0-RC1 and 3.2.1.
- Patch location: The fix is in the
sendHeaderfunction within theWebServerclass. The patch sanitizes thenameandvalueparameters by removing CR and LF characters.
Valters IT