fix(permissions): preserve substitution-bearing env prefixes - #10204
Closed
SLP-DEV1 wants to merge 3 commits into
Closed
fix(permissions): preserve substitution-bearing env prefixes#10204SLP-DEV1 wants to merge 3 commits into
SLP-DEV1 wants to merge 3 commits into
Conversation
SLP-DEV1
requested review from
LaZzyMan,
doudouOUC,
qqqys,
tanzhenxin,
wenshao and
yiliang114
as code owners
August 26, 2026 21:15
Collaborator
Collaborator
|
Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with |
Author
|
Superseded by #10212. The broader fail-safe env-prefix policy now covers #10192 as well, including substitution-bearing prefixes, while also fixing #10197's static runtime-sensitive prefixes ( |
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 this PR does
This PR prevents a saved concrete Bash allow rule from matching after Qwen strips a leading environment assignment when the original command contains shell command or process substitution. Static environment prefixes remain compatible with existing permission matching, but substitution-bearing prefixes keep their full command identity and therefore cannot collapse to the trusted main command.
Why it's needed
A command such as
X=$(printf hidden) npm --versioncan execute the substitution beforenpm --version, while the previous permission normalization could stripX=$(...)and match a savedBash(npm --version)allow rule. The shell safety layer already classifies substitution conservatively, but the saved allow rule could override that result. This crosses the confirmation boundary described in #10192.Reviewer Test Plan
How to verify
Run
npx vitest run packages/core/src/permissions/env-assignment-substitution.test.ts packages/core/src/permissions/permission-manager.test.ts packages/core/src/utils/shell-utils.test.ts. Confirm that a static prefix such asFOO=bar npm --versionstill matchesBash(npm --version), whileX=$(printf hidden) npm --version, backtick substitution, and quoted command substitution do not. The end-to-end PermissionManager regression should returnaskforX=$(printf hidden) npm --versionwhen onlyBash(npm --version)is allowed.Evidence (Before & After)
N/A — this is a non-UI permission-matching change. Before the fix, substitution-bearing leading environment assignments could be stripped before Bash rule matching. After the fix, the regression verifies that the same invocation remains
ask, while static environment-prefix compatibility is preserved.Tested on
Environment (optional)
GitHub Actions Ubuntu runner with Node.js 22. The focused Vitest command above completed successfully on the fork.
Risk & Scope
NODE_OPTIONSandGIT_CONFIG_*, is intentionally unchanged by this PR.FOO=bar npm --version; those continue to match the underlying concrete Bash rule as before.Linked Issues
Closes #10192
中文说明
此 PR 的作用
此 PR 防止在原始命令包含 shell 命令替换或进程替换时,Qwen 先移除前导环境变量赋值、再错误命中已保存的具体 Bash allow 规则。静态环境变量前缀仍保持现有权限匹配兼容性,但包含替换语义的前缀会保留完整命令身份,因此不能再被归一化成受信任的主命令。
为什么需要它
类似
X=$(printf hidden) npm --version的命令会在执行npm --version之前先执行替换内容,而之前的权限归一化可能移除X=$(...),随后命中已保存的Bash(npm --version)allow 规则。Shell 安全层本来已经会保守地处理命令替换,但已保存的 allow 规则可能覆盖这一结果。这会跨越 #10192 中描述的确认边界。Reviewer 测试计划
如何验证
运行
npx vitest run packages/core/src/permissions/env-assignment-substitution.test.ts packages/core/src/permissions/permission-manager.test.ts packages/core/src/utils/shell-utils.test.ts。确认像FOO=bar npm --version这样的静态前缀仍然可以命中Bash(npm --version),而X=$(printf hidden) npm --version、反引号替换以及带引号的命令替换都不能命中。端到端 PermissionManager 回归测试应确认:当唯一 allow 规则是Bash(npm --version)时,X=$(printf hidden) npm --version的结果为ask。证据(修改前与修改后)
N/A —— 这是非 UI 的权限匹配修改。修复前,包含替换语义的前导环境变量赋值可能在 Bash 规则匹配前被移除。修复后,回归测试验证同一调用保持为
ask,同时继续保留静态环境变量前缀的兼容行为。测试平台
环境(可选)
GitHub Actions Ubuntu runner,Node.js 22。上面的聚焦 Vitest 命令已在 fork 上成功完成。
风险与范围
NODE_OPTIONS和GIT_CONFIG_*,本 PR 有意不改变该问题。FOO=bar npm --version这类静态环境变量前缀没有破坏性变更;它们仍会像以前一样命中底层具体 Bash 规则。关联 Issue
Closes #10192