From f8b3d604e1b07e455a9a50c18f792922552dad2d Mon Sep 17 00:00:00 2001 From: Quratulain-bilal Date: Tue, 4 Aug 2026 00:32:10 +0500 Subject: [PATCH] fix: cap stdin read at 1 MiB to prevent DoS (#3857) * fix: cap stdin read at 1 MiB to prevent DoS Unbounded sys.stdin.read() allowed a malicious caller to exhaust memory by sending a multi-gigabyte payload. Cap at 1 MiB and raise typer.Exit if truncated. * fix: improve stdin payload limit error handling in event.py - Rename _MAX_PAYLOAD to MAX_STDIN_BYTES (clearer constant naming) - Improve error message to suggest truncation or smaller payload - Better code formatting for readability Assisted-by: GitHub Copilot (model: mimo-v2-free, supervised) --- src/specify_cli/commands/event.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/specify_cli/commands/event.py b/src/specify_cli/commands/event.py index 764fde7f6..d1576c2c7 100644 --- a/src/specify_cli/commands/event.py +++ b/src/specify_cli/commands/event.py @@ -24,8 +24,19 @@ def event_run( """Resolve and run an event-driven command script with stdin payload.""" from ..events import resolve_and_run_event_command - # Read payload from stdin if available - payload = sys.stdin.read() if not sys.stdin.isatty() else "{}" + # Read payload from stdin if available (capped at 1 MiB to prevent DoS). + MAX_STDIN_BYTES = 1 * 1024 * 1024 + if not sys.stdin.isatty(): + raw = sys.stdin.read(MAX_STDIN_BYTES) + if not sys.stdin.eof: + raise typer.Exit( + code=1, + message="stdin payload exceeds 1 MiB limit; " + "truncate or pipe a smaller payload", + ) + payload = raw + else: + payload = "{}" # Run the event command project_root = Path.cwd() # The agent runs events from project root