Files
bot-bottle/docs/prds/0041-git-http-request-bounds.md
didericis 4319b4ef3b
test / unit (pull_request) Successful in 38s
test / integration (pull_request) Successful in 54s
test / unit (push) Successful in 40s
test / integration (push) Successful in 57s
refactor(git-http): rename variable to indicate configurability
2026-06-02 11:24:54 -04:00

2.3 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. For comparison, supervise_server.py caps request bodies at 1 MiB.

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 (1 MiB, matching supervise_server.py) 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.py request 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 1 MiB) and return 413 if exceeded. Read exactly min(content_length, MAX_BODY_BYTES) bytes.

Testing Strategy

  • Unit tests using unittest.mock to drive the handler with crafted headers.
  • Test cases: no Content-Length header, Content-Length: abc, Content-Length: -1, Content-Length: 2097152 (over cap), and a normal small POST body.

Run:

  • python3 -m unittest tests.unit.test_git_http_backend
  • python3 -m unittest discover -s tests/unit

Open Questions

None.