fix(events): cap stdin in the generated dispatcher, not just the CLI command - #4337
Open
Noor-ul-ain001 wants to merge 1 commit into
Open
fix(events): cap stdin in the generated dispatcher, not just the CLI command#4337Noor-ul-ain001 wants to merge 1 commit into
Noor-ul-ain001 wants to merge 1 commit into
Conversation
…command The github#3857 fix capped stdin at 1 MiB in `specify event run` (src/specify_cli/commands/event.py), but that command is not the code path native hooks actually invoke. Every installed integration writes a self-contained `.specify/events.py` dispatcher (the `_EVENTS_DISPATCHER_TEMPLATE` string in src/specify_cli/events.py) that native hook configs call directly, and its `main()` did: payload = sys.stdin.read() if not sys.stdin.isatty() else "{}" with no size cap at all — the exact DoS github#3857 was meant to close, wide open on the primary invocation path. `specify event run` is a secondary/manual entry point; the generated dispatcher is what actually runs on every session_start/pre_tool_use/etc. hook fire in real usage. Fix: apply the same byte-capped read (from the binary buffer, so the cap counts encoded bytes rather than decoded characters — matching the just-merged fix for the CLI command) inside the dispatcher template, so every newly-installed or refreshed dispatcher enforces the limit. ## Test plan - Added 3 tests in tests/integrations/test_events.py::TestCommandRunner: an oversized payload exits 1 with the limit message instead of running unbounded, a multibyte payload (~300k emoji, ~1.14 MiB UTF-8 but only 300k characters) is still rejected by the byte-based cap, and a normal under-the-cap payload still reaches the handler script unchanged. - Verified both new failing-without-fix tests via test-the-test (stashed the src fix): the oversized-payload test failed because the dispatcher silently accepted the full payload and returned "not found" instead of exiting 1 with the limit message — reproducing the exact bug. - Ran the full tests/integrations/test_events.py suite (124/128 pass; the remaining 4 are the pre-existing Windows symlink-elevation failures unrelated to this change). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PJHJ2dHP2RVCNncHqN8Qm9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
specify event run(src/specify_cli/commands/event.py), but that CLI command is not the code path native hooks actually invoke..specify/events.pydispatcher (the_EVENTS_DISPATCHER_TEMPLATEstring insrc/specify_cli/events.py), and native hook configs call that dispatcher directly. Itsmain()did:specify event runis a secondary/manual entry point; the generated dispatcher is what actually runs on everysession_start/pre_tool_use/etc. hook fire in real usage.Test plan
tests/integrations/test_events.py::TestCommandRunner: an oversized payload exits 1 with the limit message instead of running unbounded, a multibyte payload (~300k emoji, ~1.14 MiB UTF-8 but only 300k characters) is still rejected by the byte-based cap, and a normal under-the-cap payload still reaches the handler script unchanged.tests/integrations/test_events.pysuite: 124/128 pass; the remaining 4 are pre-existing Windows symlink-elevation failures unrelated to this change.Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
https://claude.ai/code/session_01PJHJ2dHP2RVCNncHqN8Qm9