Repository navigation
fix(cli): critical security fixes for subagent permissions, writeFile boundary, and policy bypass - #12248
fix(cli): critical security fixes for subagent permissions, writeFile boundary, and policy bypass#12248johnpippett wants to merge 2 commits into
Conversation
… boundary, and policy bypass - Remove subagent unconditional allow-all tool permission override - Add throwIfFileIsSecurityConcern to writeFile tool - Respect dynamic tool policy evaluation in permissionChecker
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
There was a problem hiding this comment.
1 issue found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="extensions/cli/src/permissions/permissionChecker.ts">
<violation number="1" location="extensions/cli/src/permissions/permissionChecker.ts:200">
P1: Invalid dynamic policy fallback is fail-open (`basePermission`), which can bypass dynamic restrictions when evaluator output is unexpected.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| if (!validPolicies.includes(evaluatedPolicy)) { | ||
| return { | ||
| permission: "exclude", | ||
| permission: basePermission, |
There was a problem hiding this comment.
P1: Invalid dynamic policy fallback is fail-open (basePermission), which can bypass dynamic restrictions when evaluator output is unexpected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At extensions/cli/src/permissions/permissionChecker.ts, line 200:
<comment>Invalid dynamic policy fallback is fail-open (`basePermission`), which can bypass dynamic restrictions when evaluator output is unexpected.</comment>
<file context>
@@ -158,17 +189,26 @@ export function checkToolPermission(
+ if (!validPolicies.includes(evaluatedPolicy)) {
return {
- permission: "exclude",
+ permission: basePermission,
matchedPolicy,
};
</file context>
| permission: basePermission, | |
| permission: getMostRestrictivePermissionPolicy(basePermission, "ask"), |
|
This PR is directionally important because it fixes three places where permission policy can be bypassed below the user-facing intent. The regression boundary I would want around it:
The subtle failure mode is "allow" becoming a universal default. For agent tools, allow should be scoped to exact tool/action/resource, and dynamic checks should run as a final pre-execution gate. If any layer cannot produce a valid decision, the tool should not run. That turns the fix from a one-off patch into a permission invariant maintainers can preserve across future CLI/subagent changes. |
Deny the tool call when the dynamic policy evaluator throws or returns an invalid value. Before, invalid output kept the static permission, which could allow the call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Fixed in 84856a5. The permission checker now denies the tool call when the policy evaluator throws or returns an invalid value. Before, it kept the static permission. New tests cover undefined, null, empty, wrong-case and non-string output, and an evaluator that throws. |
|
I am closing this pull request because I will not sign the CLA. The findings in the description stay available here if you want to fix them yourselves. Thank you for the review. |
Summary
Addresses three critical/high security findings from the 2026-04-28 AI Tooling Security Audit:
Subagent bypasses permissions (Critical) — Removed the hard-coded
policies: [{ tool: "*", permission: "allow" }]override inextensions/cli/src/subagent/executor.tsso subagents now inherit the main agent's tool permission policies instead of unconditionally allowing all tools.writeFile no boundary (High) — Added
throwIfFileIsSecurityConcernchecks to both thepreprocessandrunfunctions inextensions/cli/src/tools/writeFile.ts, aligning it with the security posture ofreadFileandedittools.Policy bypass (High) — Fixed
extensions/cli/src/permissions/permissionChecker.tsso that dynamic tool policy evaluation (e.g., terminal command security analysis) is respected rather than being overridden by static userallowpolicies. The fix takes the most restrictive of the static policy and the dynamically evaluated policy, and gracefully handles invalid evaluator responses.Test Results
permissionChecker.test.tsandpermissionChecker.integration.test.tsupdated and passing.Summary by cubic
Fixes three critical/high security issues in the CLI: subagents now inherit tool permissions,
writeFileenforces path safety checks, and dynamic tool policy evaluation can’t be bypassed.writeFileboundary: addedthrowIfFileIsSecurityConcernin both preprocess and run to matchreadFile/editposture.permissionCheckernow takes the most restrictive result between static policy and dynamic evaluation, and safely handles invalid evaluator outputs.permissionCheckerunit/integration tests; all CLI tests pass.Written for commit 5b77e11. Summary will update on new commits. Review in cubic