Conversation
MCP-005 covers the Python path-safety case; the TypeScript half was missing. Mirrors CSDK-012, including its coarse-signal caveat — it flags any filesystem write rather than only unnormalized paths, because TS path-normalization analysis is not yet wired. Deployment is what sharpens this for MCP. A stdio server is launched as a subprocess by whatever client the user is running, so it inherits that user's own filesystem permissions rather than a service account's, and a write escaping its intended directory reaches the user's home directory, dotfiles, and SSH keys. The server also cannot see the injection: it receives a well-formed tools/call for a path it has no way to distinguish from a legitimate one.
|
Thanks @bradAGI, this is a careful pair. The rule is schema-clean ( The thing to sort out is the ID. One more note: every shipped rule needs a rationale doc in Happy to take this once the numbering is settled. |
|
Selected for merge. This pair keeps Closing #80 (PHP typed parameters) and #100 (PHP idempotency), which claimed the same id for different rules. Several PRs claimed the same ids independently. We are resolving each id to a single pair rather than renumbering, so the competing PRs are being closed — the rules themselves were not rejected. Merge the engine side first so a gap fails safe: a fixture for an unshipped rule is harmless, a rule with no fixture turns |
Engine half of a coordinated pair with trustabl/agent-reliability-rules#94, on a branch of the same name so the rules-sync job resolves the matching pack rather than main. Neither half should merge alone — check-rules-sync.sh fails if they do. Mirrors mcp/path_safety.yaml into testdata/rules-fixture and adds a fire and a silent case to policyRuleCases, as TestPolicyRules_AllRulesCovered requires. MCP-005 covers the Python path-safety case; the TypeScript half was missing. The silent case applies the remediation the fix text prescribes for the common shape — derive the name server-side rather than accepting a path over the protocol — instead of merely removing the write.
MCP-005 covers the Python path-safety case; the TypeScript half was missing. Mirrors CSDK-012 — the TS half of the Claude SDK pair — including its coarse-signal caveat, stated in the explanation so the finding is honest about itself: it flags any filesystem write, not only unnormalized paths, because TS path-normalization analysis isn't wired yet. Confidence 0.5 to match.
Deployment is what sharpens this for MCP, and it's the part worth having in the finding text. A stdio server is launched as a subprocess by whatever client the user is running, so it inherits that user's own filesystem permissions, not a service account's. A write escaping its intended directory doesn't hit a sandbox — it reaches the user's home directory, dotfiles, and SSH keys.
The second half is that the server cannot see the injection. It receives a well-formed
tools/callfor a path it has no way to distinguish from a legitimate one, so there's no server-side signal to alert on. Containment has to be structural.The fix names the stronger remedy for the common case: derive the filename server-side from an id rather than accepting a path over the protocol at all.
Verification — engine built at
main:Fire (
writeFileSync(notePath, body)withnotePathfrom the tool schema):MCP-029Silent (server-derived id, no caller-supplied path): no findings
No new predicates, so no
schema_versionbump.