2.2 KiB
PRD 0041: Git HTTP Request Bounds
- Status: Active
- Author: didericis-codex
- Created: 2026-06-02
- Issue: #138
Summary
Add Content-Length validation and a body-size cap to git_http_backend.py so malformed or oversized smart-HTTP requests fail cleanly rather than crashing the handler or exhausting memory.
Problem
bot_bottle/git_http_backend.py calls int(self.headers.get("Content-Length", 0)) without catching ValueError. A request with a non-numeric Content-Length raises an unhandled exception in the request handler.
The handler reads the full declared length into memory before passing the body to git http-backend with no upper bound. A local or compromised client can force arbitrarily high memory use.
Goals / Success Criteria
- A missing or non-numeric Content-Length returns HTTP 400.
- A negative Content-Length returns HTTP 400.
- A body larger than the cap (100 MiB) returns HTTP 413.
- Valid Git smart-HTTP pushes and fetches continue to work.
- Unit tests cover: missing length, non-numeric length, negative length, over-cap length, and a valid push/fetch passthrough.
Non-goals
- No changes to git-gate authentication or route logic.
- No changes to
supervise_server.py. - No streaming / chunked-transfer-encoding support.
- No TLS changes.
Scope
In scope:
bot_bottle/git_http_backend.pyrequest parsing and body reading.- Unit tests in
tests/unit/test_git_http_backend.py.
Out of scope:
- Integration tests that drive a real Git client through the handler.
Design
Wrap the Content-Length parse in a try/except and return 400 on ValueError. Add an explicit check for negative values. After parsing, compare the declared length against a module-level MAX_BODY_BYTES constant (default 100 MiB) and return 413 if exceeded. Read exactly min(content_length, MAX_BODY_BYTES) bytes.
Testing Strategy
- Unit tests using
unittest.mockto drive the handler with crafted headers. - Test cases: no Content-Length header,
Content-Length: abc,Content-Length: -1, a declared length aboveMAX_BODY_BYTES, and a normal small POST body.
Run:
python3 -m unittest tests.unit.test_git_http_backendpython3 -m unittest discover -s tests/unit
Open Questions
None.