Decompose security review #003 findings into 17 fix tasks and 1 review task
Address 4 critical, 8 warning, and 5 suggestion findings from the security and bug review by creating atomic, dependency-ordered tasks: Critical fixes (C1-C4): rate limiter IP source (ADR-025), InFlightCounter increment + drain interval, connector timeout ceiling (ADR-026), JSON format without log file. Validation tightening (W1, W2): upstream host validation, ACME contact email validation. Robustness (W3, W4, W5, W12): upstream URI error handling (502 not silent drop), admin socket resource limits (ADR-027), TlsMode wildcard mismatch, http_port u32→u16. Code quality (W6, W10, W11, S1, S3, W8/W9): config type consolidation, TokenBucket field visibility, reload_mutex #[cfg(test)], dead code removal, root cert count logging, misleading test names. Test coverage (S10): rate limiter ConnectInfo tests (depends on C1 fix). Review: post-security-fix-review checkpoint covering all critical fixes and sensitive config consolidation path.
This commit is contained in:
80
tasks/fix/upstream-uri-error-handling.md
Normal file
80
tasks/fix/upstream-uri-error-handling.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: fix/upstream-uri-error-handling
|
||||
name: Return 502 on upstream URI parse failure instead of dropping query string (W3)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: low
|
||||
impact: component
|
||||
level: implementation
|
||||
review_findings: [W3]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
`build_upstream_uri` silently drops the query string on parse failure and
|
||||
`.unwrap()`s the fallback. This corrupts requests — the upstream receives the
|
||||
wrong URL with no query parameters, and neither the client nor operator is
|
||||
notified. The `.unwrap()` on the fallback could also panic.
|
||||
|
||||
The spec (proxy.md request forwarding step 1) states: "If URI construction
|
||||
fails (e.g., the resulting URI is malformed), the proxy must return 502 Bad
|
||||
Gateway and log the error at warn level. The proxy must never silently drop
|
||||
parts of the URI."
|
||||
|
||||
### Changes Required
|
||||
|
||||
**`src/proxy/handler.rs`**:
|
||||
- Change `build_upstream_uri` to return `Result<Uri, ()>`:
|
||||
```rust
|
||||
fn build_upstream_uri(scheme: &str, upstream: &str, original_uri: &Uri) -> Result<Uri, ()> {
|
||||
let path = original_uri.path();
|
||||
let query = original_uri
|
||||
.query()
|
||||
.map(|q| format!("?{}", q))
|
||||
.unwrap_or_default();
|
||||
let uri_string = format!("{}://{}{}{}", scheme, upstream, path, query);
|
||||
uri_string.parse::<Uri>().map_err(|e| {
|
||||
warn!(error = %e, uri = %uri_string, "failed to parse upstream URI");
|
||||
})
|
||||
}
|
||||
```
|
||||
- Update `proxy_handler` to handle the `Err` case:
|
||||
```rust
|
||||
let upstream_uri = match build_upstream_uri(&upstream_scheme, &upstream, req.uri()) {
|
||||
Ok(uri) => uri,
|
||||
Err(()) => {
|
||||
log_upstream_error!(&host_owned, &upstream_addr, "malformed upstream URI");
|
||||
let duration_ms = start.elapsed().as_millis() as u64;
|
||||
log_request!(&client_ip, &host_owned, &method, &path, 502u16, &upstream, duration_ms);
|
||||
return StatusCode::BAD_GATEWAY.into_response();
|
||||
}
|
||||
};
|
||||
```
|
||||
- Update the existing unit tests for `build_upstream_uri` to handle the
|
||||
`Result` return type.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `build_upstream_uri` returns `Result<Uri, ()>` instead of `Uri`
|
||||
- [ ] URI parse failure logs a warning with the malformed URI string
|
||||
- [ ] URI parse failure returns 502 Bad Gateway to the client
|
||||
- [ ] No `.unwrap()` calls in `build_upstream_uri`
|
||||
- [ ] Query strings are never silently dropped
|
||||
- [ ] Existing unit tests updated for `Result` return type
|
||||
- [ ] `cargo test` passes
|
||||
- [ ] `cargo clippy` passes with no warnings
|
||||
|
||||
## References
|
||||
|
||||
- docs/architecture/proxy.md — request forwarding step 1, URI error handling
|
||||
- docs/reviews/003-security-and-bug-review.md — W3 finding
|
||||
- src/proxy/handler.rs — `build_upstream_uri`, `proxy_handler`
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled on completion
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Reference in New Issue
Block a user