Skip to content

security: bound Content-Length parsing in viewer server#875

Open
Sunil56224972 wants to merge 1 commit into
usestrix:mainfrom
Sunil56224972:pr1-content-length
Open

security: bound Content-Length parsing in viewer server#875
Sunil56224972 wants to merge 1 commit into
usestrix:mainfrom
Sunil56224972:pr1-content-length

Conversation

@Sunil56224972

Copy link
Copy Markdown

Summary

The viewer server's _read_body() method has two issues with Content-Length handling:

1. Unbounded memory allocation (OOM DoS) — Medium Severity

A client can send Content-Length: 999999999999 and force the server to attempt allocating an enormous buffer via self.rfile.read(length), causing an out-of-memory denial of service against the viewer process.

Fix: Added _MAX_BODY_BYTES = 2 * 1024 * 1024 (2 MiB) cap. Any Content-Length above this limit causes _read_body() to return an empty dict, so the endpoint returns its normal validation error.

2. Unhandled ValueError on malformed Content-Length — Low Severity

int(self.headers.get('Content-Length') or 0) raises ValueError if the header contains a non-integer value (e.g. 'abc' or '12,34'). The outer except Exception catches it but produces a 500 + full stack trace in logs for what should be a malformed request.

Fix: Wrapped the int() conversion in try/except (ValueError, OverflowError) so malformed headers degrade gracefully.

Files changed

  • strix/viewer/server.py

Testing

  • Verified the fix preserves all existing endpoint behavior for valid requests
  • Invalid/oversized Content-Length values now return empty body (endpoints handle this via their existing validation)

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.
@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR hardens viewer request-body parsing.

  • Caps declared request bodies at 2 MiB.
  • Treats malformed, negative, and oversized Content-Length values as empty bodies.

Confidence Score: 5/5

The PR appears safe to merge with no actionable issues identified.

The viewer now rejects invalid or excessive declared body lengths before reading them, while valid request bodies continue through the existing JSON parsing path.

Important Files Changed

Filename Overview
strix/viewer/server.py Adds bounded and exception-safe Content-Length parsing without introducing an actionable defect.

Reviews (1): Last reviewed commit: "security: bound Content-Length parsing i..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant