cloudflare / cloudflare/pingora
Malformed HTTP requests bypass ProxyHttp layer, preventing custom error handling and logging
- Dominant language
- Rust
- Stars
- 27.4k
- Forks
- 1.7k
- Avg merge
- 6h 22m
- Merged PRs (30d)
- 3
Description
Hello,
### Context & Current Behavior
When Pingora receives an HTTP request with a malformed URL, the error is handled internally at the `Server` layer. Consequently, the request never reaches the `ProxyHttp` layer. Because of this, it is impossible to intercept or log these invalid requests via `fail_to_proxy` or any other phase of the proxy lifecycle.
Instead, Pingora automatically generates a hardcoded response using `generate_error()`:
--- server.rs
```rust
pub fn generate_error(error: u16) -> ResponseHeader {
match error {
/* common error responses are pre-generated */
502 => error_resp::HTTP_502_RESPONSE.clone(),
400 => error_resp::HTTP_400_RESPONSE.clone(),
_ => error_resp::gen_error_response(error),
}
}
```
--- error_resp.rs
```rust
pub fn gen_error_response(code: u16) -> ResponseHeader {
let mut resp = ResponseHeader::build(code, Some(4)).unwrap();
resp.insert_header(header::SERVER, &SERVER_NAME[..])
.unwrap();
resp.insert_header(header::DATE, "Sun, 06 Nov 1994 08:49:37 GMT")
.unwrap(); // placeholder
resp.insert_header(header::CONTENT_LENGTH, "0").unwrap();
resp.insert_header(header::CACHE_CONTROL, "private, no-store")
.unwrap();
resp
}
```
### The Problem
This behavior creates a major limitation for production environments where **every single request** needs to be processed, logged, or analyzed (e.g., for security auditing, SIEM logging, or WAF/attack detection).
Currently, I am forced to maintain a local patched version of Pingora to bypass this, which is unsustainable for long-term production use.
There are 4 critical points regarding the current implementation:
1. **Lack of Propagation:** Internal server errors (like a 400 Bad Request due to a malformed URL) should ideally be forwarded to the `ProxyHttp` layer so users can catch and handle them (ex: fail_to_proxy).
2. **Hardcoded / Inconsistent Headers:** The generated response is not customizable. Furthermore, it includes a hardcoded placeholder date (`Sun, 06 Nov 1994 08:49:37 GMT`) which is inconsistent with real-time traffic.
3. **Security Information Disclosure:** Leaking the `SERVER` header (`Pingora`) in these errors exposes the underlying technology stack to potential attackers. Security best practices recommend stripping or customizing these headers to prevent fingerprinting.
4. **Risk of Panics:** The extensive use of `.unwrap()` during the header insertion sequence presents a potential crash/panic risk in edge-case scenarios.
---
### Proposed Solution / Discussion
We need a structural solution to allow these early-stage errors to be intercepted or customized within the `ProxyHttp` ecosystem, or at least provide a hook to override the default error response generation.
Is there already a planned roadmap or architectural design to address this architectural gap?
I would be more than happy to contribute and open a PR for this, but since it impacts the internal core workflow of the framework, I would appreciate some guidance from the maintainers on the preferred alignment and design pattern to follow.
---
**Pingora version**: 0.8.1
Contributor guide
Research direction
Start by reading server.rs and error_resp.rs around generate_error() and gen_error_response(), then trace the ProxyHttp lifecycle and fail_to_proxy entry point. The issue is ready when maintainers agree on an interception or response-customization design and its expected behavior for malformed requests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100