Skip to content

fix: fail closed on an unknown or wrong-typed command in the worker codec - #1150

Closed
FSM1 wants to merge 3 commits into
mainfrom
fix/1051-fail-closed-build-command
Closed

fix: fail closed on an unknown or wrong-typed command in the worker codec#1150
FSM1 wants to merge 3 commits into
mainfrom
fix/1051-fail-closed-build-command

Conversation

@FSM1

@FSM1 FSM1 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

buildCommand switched over CommandDescriptor with no default arm, so an unknown kind fell out returning undefined and only failed because the wasm-bindgen glue happened to reject it — fail-closed by accident, and inconsistent with the three sibling switches in the same file that already fail closed deliberately.

The sharper case was a known kind carrying a wrong-typed field. { kind: 'rename', node: <16 bytes>, newName: 12345 } reached wasm.Command.rename(nodeId, 12345) and wasm-bindgen's USVString marshalling coerced it, renaming the node to "12345" instead of rejecting the command. Reachable from a version-skewed follower build: the private-port relay validates the command shape and deliberately leaves field validation to the codec, so that division only holds if the codec enforces it.

What changed

  • Every field the builders read is checked against the type the protocol declares — byte arrays must be a real Uint8Array, strings a real string, opId a real bigint. The checkers take unknown, because the descriptor arrives as plain data across a realm boundary and its static type is a claim, not a guarantee.
  • nodeKind and permission no longer fall through to Folder/Write on an unrecognised literal; they reject it. That was the same silent-coercion class, one layer down.
  • A default arm binds the descriptor to never and throws. Verified by temporarily adding a seventeenth kind to CommandDescriptor: tsc fails with Type '{ kind: "probeNewKind"; … }' is not assignable to type 'never' at that binding, so a new kind cannot be added without a builder.

Valid commands are unaffected — every check passes through the value it validated.

Tests

packages/client/src/worker/commandCodec.test.ts gains five refusal cases driven against a permissive fake whose every builder succeeds, so only the codec's own checks can reject: an unknown kind, a numeric newName and a null name, a string where a public key belongs and an array where a node id belongs, an unrecognised nodeKind and permission, and a number opId. A sixth asserts the accept side of both mirror enums — 'folder' and 'write', not only the literal each mapper tests first.

Not in this PR

The byte and string arguments of beginWrite, snapshot, download and openContentStream reach WASM from the same untrusted message with the same coercion, and passArray8ToWasm0 turns a 16-character string into sixteen zero bytes rather than rejecting it. That is #1154, which reuses the checkers this PR introduces.

Gates

pnpm typecheck 0, pnpm test 0, pnpm lint 0, pnpm lint:tracker-refs 0.

Closes #1051

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 792882b5-0584-4c7e-9bdb-87618df56840

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

FSM1 added 3 commits August 7, 2026 15:32
…odec

buildCommand had no default arm, so an unknown kind fell out as undefined and
only failed by accident of the wasm-bindgen glue. A known kind carrying a
wrong-typed field was worse: wasm-bindgen coerced a numeric newName through
USVString and renamed the node, rather than rejecting the command.

Every field the builders read is now checked against the type the protocol
declares, and the default arm binds the descriptor to never so a new command
kind without a builder is a compile error.

Closes #1051
@FSM1
FSM1 force-pushed the fix/1051-fail-closed-build-command branch from d681e47 to fc548ff Compare August 7, 2026 13:33
@FSM1

FSM1 commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

Consolidated into #1145. Both changes are fail-closed fixes in packages/client/src/worker/** on disjoint files, so they are reviewed together instead of costing two review slots for a hundred lines each. This branch's three commits were cherry-picked onto #1145 unchanged, and the combined branch passes pnpm typecheck, pnpm test, pnpm lint and pnpm lint:tracker-refs. Nothing is lost; this branch is not deleted.

@FSM1 FSM1 closed this Aug 7, 2026
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.

web: fail closed in buildCommand instead of coercing wrong-typed command fields

1 participant