From 452105a658f94950767dc37c032a386fb8126411 Mon Sep 17 00:00:00 2001 From: Sunil Date: Sun, 26 Jul 2026 00:07:02 +0530 Subject: [PATCH] security: bound Content-Length parsing in viewer server The viewer's _read_body() method reads Content-Length bytes from the request without any upper bound. A client can send a crafted Content-Length: 999999999999 header and force the server to attempt allocating an enormous buffer, causing an out-of-memory denial of service against the viewer process. Additionally, a non-integer Content-Length value (e.g. 'abc' or '12,34') causes int() to raise ValueError. The outer handler catches it as a generic 500, but the real issue is a malformed request that should be silently dropped. Fixes: 1. Add _MAX_BODY_BYTES (2 MiB) cap -- any Content-Length above this limit causes _read_body to return an empty dict (same as a missing body), so the endpoint returns its normal validation error. 2. Wrap the int() conversion in try/except (ValueError, OverflowError) so malformed headers degrade gracefully instead of producing a 500 with a full stack trace in the log. --- strix/viewer/server.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/strix/viewer/server.py b/strix/viewer/server.py index 77cee58d1..689b356fc 100644 --- a/strix/viewer/server.py +++ b/strix/viewer/server.py @@ -187,8 +187,17 @@ def do_POST(self) -> None: logger.exception("viewer request failed: POST %s", path) self._send_json(HTTPStatus.INTERNAL_SERVER_ERROR, {"error": "internal error"}) + # Cap on request body size so a client cannot force unbounded + # memory allocation by sending a huge Content-Length. + _MAX_BODY_BYTES = 2 * 1024 * 1024 # 2 MiB + def _read_body(self) -> dict[str, Any]: - length = int(self.headers.get("Content-Length") or 0) + try: + length = int(self.headers.get("Content-Length") or 0) + except (ValueError, OverflowError): + return {} + if length < 0 or length > self._MAX_BODY_BYTES: + return {} raw = self.rfile.read(length) if length else b"" try: body = json.loads(raw or b"{}")