fix(brainstorming): cap WebSocket frame payloads#1555
Open
therahul-yo wants to merge 1 commit into
Open
Conversation
5 tasks
|
Review note after reading the issue, PR body, and diff: This is a focused slice of #1446: it only addresses the WebSocket advertised-payload allocation path and leaves the unrelated I did not see a code-level blocker in the patch. The important property is that the 64-bit length is checked before Process / verification items for reviewers:
|
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.
What problem are you trying to solve?
Issue #1446 reports that
skills/brainstorming/scripts/server.cjstrusts the 64-bit WebSocket payload length from a client frame and then allocatesBuffer.alloc(payloadLen). Because the brainstorm companion server listens on localhost, a local process or browser context can advertise a huge frame length and make the server attempt a very large allocation.This PR addresses only that concrete payload-size allocation bug from #1446. It does not attempt to fix the other two unrelated items in the bundled issue.
What does this PR change?
Adds a 10 MiB maximum WebSocket frame payload size, rejects oversized advertised payloads before allocation, and exports the limit for protocol tests. Adds a regression test that constructs an oversized 64-bit frame header and verifies
decodeFrame()rejects it from the header alone.Is this change appropriate for the core library?
Yes. The brainstorm companion server is part of the core
brainstormingskill, and this hardens its built-in zero-dependency WebSocket parser for all users. It is not project-specific, team-specific, or tied to a third-party integration.What alternatives did you consider?
I considered limiting only complete frames after
buffer.length >= totalLen, but that still leaves the parser willing to wait for an enormous declared payload and keeps the bad length in control flow. Rejecting immediately after reading the extended length avoids the risky allocation path and makes the behavior explicit.I also considered changing the server to use a WebSocket dependency, but Superpowers is intentionally dependency-light and this bug can be fixed locally in the existing parser.
Does this PR contain multiple unrelated changes?
No. This PR only caps inbound brainstorm WebSocket frame payloads and adds protocol-level coverage for that limit.
Existing PRs
I searched open and closed PRs for
1446,escape_for_json,payload-size, andfind-polluter. I found #1504, which hardens a different brainstorm-server path (handleMessagenull payload handling), and #1483, which addressed the separatefind-polluter.shspaced-path issue from #1446 and was closed. I did not find an open or merged PR that caps WebSocket frame payload length before allocation.Environment tested
System Node/npm on this machine is currently broken because Homebrew Node cannot load
/opt/homebrew/opt/llhttp/lib/libllhttp.9.3.dylib. I used the Codex bundled Node runtime for the focused protocol test instead.New harness support (required if this PR adds a new harness)
Not applicable. This PR does not add or modify harness support.
Clean-session transcript for "Let's make a react todo list"
Not applicable. This PR does not add or modify a harness integration.
Evaluation
obra/superpowersand contribute. I reviewed open issues and PRs, rejected test-driven-development:@testing-anti-patterns.mdreference uses@prefix that doesnt resolve #1529 as duplicate because fix(tdd): link testing anti-patterns reference #1532 already merged the focused fix, then selected the WebSocket payload-size item from v5.0.7: three latent bugs found in static review (escape_for_json control-char gap, server.cjs payload-size DoS, find-polluter.sh unquoted loop) #1446.decodeFrame()accepted a 64-bit advertised payload length and would use that length inBuffer.alloc(payloadLen)once enough bytes were buffered. After the change, lengths aboveMAX_FRAME_PAYLOAD_BYTESthrowWebSocket frame payload exceeds maximum allowed sizeimmediately after header decoding, before payload allocation.Verification commands run:
Results:
Rigor
superpowers:writing-skillsand completed adversarial pressure testing (paste results below)This PR changes parser code and a protocol test, not behavior-shaping skill prose. The regression test exercises an adversarial oversized 64-bit WebSocket frame header designed to trigger the reported allocation path.
Human review
The complete two-file diff was shown in the Codex session and the human partner explicitly approved opening the PR.