In October 2022, a critical vulnerability surfaced in the Rust ecosystem—specifically in the way the conduit-hyper crate handled incoming HTTP requests. This vulnerability, registered as CVE-2022-39294, shows how oversight in handling input sizes can open the door to denial-of-service (DoS) attacks, even in modern, memory-safe languages like Rust.
In this article, we’ll break down what went wrong, demonstrate the exploit with code, explain the fix, and discuss why you probably shouldn’t put conduit-hyper directly on the frontlines of your web infrastructure.
What Is conduit-hyper?
conduit-hyper is a bridge library that connects conduit—a web application interface in Rust—to hyper, a fast HTTP implementation. It’s used as a web server layer in some Rust applications, notably in parts of crates.io (the public Rust package registry).
The Problem
Before version .4.2, conduit-hyper did not enforce any limit on how big a request’s body could be. This meant attackers could send an HTTP request with a huge Content-Length header, and conduit-hyper would try to read the entire payload into memory by calling hyper::body::to_bytes with no checks.
Why is this so dangerous?
- No Limit: Without bounds, attackers can ask the server to allocate hundreds of megabytes or even gigabytes of memory.
- Out-of-Memory: The server will try to honor the request until it runs out of memory, which could lead to a Rust panic and bring down the process (DoS).
- Low Effort, High Impact: The attacker doesn’t need many resources—just a script to send a malformed request.
Real-World Risk
While conduit-hyper is used in core Rust infrastructure, like crates.io, crates.io itself is not affected. This is because they run behind a cloud layer that filters out these massive, bogus requests before they even reach the Rust service.
However, if you were to use conduit-hyper in your public-facing application, this vulnerability could bring your server down with a single malicious request.
Exploit in Simple Terms
Suppose you run a conduit-hyper server at http://localhost:400, here’s what an attack could look like using curl and a little bash magic (don’t run this on a real target!).
# Generate a request with gigantic Content-Length
curl -X POST http://localhost:400/upload \
-H "Content-Type: application/octet-stream" \
-H "Content-Length: 100000000" \
--data-binary "@<(head -c 100000000 /dev/zero)"
Here’s a simplified Rust code snippet before the fix
// This is not safe in the original pre-.4.2 conduit-hyper
use hyper::body::to_bytes;
async fn handle_request(req: Request<Body>) -> Response<Body> {
// No size checking!
let body_bytes = to_bytes(req.into_body()).await.unwrap();
// Use body_bytes as needed
Response::new(Body::from("OK"))
}
There’s no guard here: if the request is huge, the server will panic when memory runs out.
The Fix: Setting a Reasonable Limit
The fix landed in conduit-hyper .4.2, where the maximum allowed body size per request is set at 128 MiB.
Now, the code checks for size first
// Pseudocode for fixed logic (since conduit-hyper code is internal)
use hyper::Request;
use hyper::body::HttpBody;
const MAX_BODY_SIZE: usize = 134_217_728; // 128 MiB
async fn safe_handle_request(req: Request<Body>) -> Response<Body> {
let mut size = usize;
let mut body = req.into_body();
while let Some(chunk) = body.data().await {
let chunk = chunk.unwrap();
size += chunk.len();
if size > MAX_BODY_SIZE {
// Reject request gracefully
return Response::builder()
.status(400)
.body(Body::from("Request body too large"))
.unwrap();
}
}
// ... proceed normally ...
Response::new(Body::from("OK"))
}
Responsible Disclosure & References
The conduit-hyper team promptly fixed the issue and released a patch. You can read the official announcements and more technical details here:
- Official CVE Record - CVE-2022-39294
- conduit-hyper changelog .4.2
- hyper::body::to_bytes documentation
Should You Use conduit-hyper?
Even with this vulnerability fixed, conduit-hyper is not recommended for direct use in public-facing servers. The maintainers themselves caution against using it for production workloads, especially without additional layers of defense (like a reverse proxy or firewall).
Conclusion
CVE-2022-39294 in conduit-hyper serves as a textbook case: trust, but verify. Even solid, memory-safe code can fail if you don’t keep attacker behavior in mind and add the right guards before trusting client input.
If you maintain a Rust webservice, always check your dependencies for updates and advisories. And if you have to accept large file uploads, make sure you’re policing those Content-Length headers!
Timeline
Published on: 10/31/2022 19:15:00 UTC
Last modified on: 07/11/2023 20:51:00 UTC