makecindy / makecindy/cindy

auto-review: POSIX 侧的动态写目标($DEST / $LOGFILE)同样静态不可证,当前按相对路径拼进工作区落灰区

Open
#2,622 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
2.7k
Forks
395
Avg merge
21h 48m
Merged PRs (30d)
776

Description

## 结论

`#2560` 修好了 PowerShell 侧「写目标要到运行期才知道」的洞:`Set-Content "$env:windir\System32\drivers\etc\hosts" owned` 里的目标不匹配盘符 → `isAbsolutePath` 判否 → `normalizeTarget` 把它当**相对路径拼到工作区下** → 系统写看起来落在区内、掉进灰区可被轻量 reviewer 放行。现在这类目标一律返回不可证哨兵。

**POSIX 侧有完全相同的洞,`#2560` 有意没动**,因为改它的代价是一次独立的口径裁决,不是补漏。

## 实测(`workspaceRoots: ['/repo']`)

| 命令 | 当前判档 | 说明 |
|---|---|---|
| `cp payload $DEST` | `prompt` | 目标不可证,被当相对路径拼到 `/repo/$DEST` |
| `cp payload "$HOME/x"` | `prompt` | 同上 |
| `cp payload ${DEST}/x` | `prompt` | 同上 |
| `cp payload "$(pwd)/x"` | `prompt` | 子命令替换 |
| `echo x > $LOGFILE` | `prompt` | 重定向目标同样不可证 |
| `tee $OUT` | `prompt` | 参数写通道 |
| `cp a "$TMPDIR/b"` | `prompt` | — |
| `cp payload /etc/hosts` | `prompt-each-time` | 静态路径,红线正常 |
| `rm -f $TARGET` | `prompt-each-time` | 这条是被**别的**规则(强制删除)拦住的,不是目标判定 |

也就是说:`DEST=/etc; cp payload "$DEST/hosts"` 这类写法在 POSIX 侧仍然绕过系统写红线。

## 为什么 #2560 没顺手一起改

按 PowerShell 侧那套「任何含 `$` 的目标一律哨兵」直接套到 POSIX,会把上表里 `cp a "$TMPDIR/b"`、`echo x > $LOGFILE`、`cp payload "$HOME/x"` 全部变成 `prompt-each-time`(哨兵是无条件必问,且不可记住)。这些是 macOS / Linux 上最常见的日常写法,命中频率远高于 PowerShell 侧 —— 属于会被用户直接感知的打扰面变化,需要产品口径拍板,而不是在一个「补 PowerShell 漏项」的 PR 里默默扩大。

`#2560` 的测试里为此留了一条**显式**断言,让这个不对称不是隐含的:

```ts
// POSIX 侧有意仍落灰区:改它会把 `cp a "$TMPDIR/b"`、`echo x > $LOGFILE` 这类日常命令
// 全打成硬弹窗,是超出本 PR 的口径变更,已单独立案。
expect(classifyShellCommand('cp payload $target', win, { platform: 'win32' })).toBe('prompt');
```

## 需要裁决的点

1. **要不要收**:这是个真实绕过,但打扰面明显。是接受打扰、还是接受这个洞?
2. **若要收,怎么降低打扰**。几个可选方向,各有代价:
- 只对**能证明会落进系统目录**的形态收(例如解析 `$HOME` / `$TMPDIR` 这类已知安全变量,其余哨兵)—— 需要一张环境变量白名单,且白名单本身是新的信任面;
- 只在目标的**根**不可证时收(`"$DEST/x"` 收、`"/repo/$name"` 不收)—— 但这**不成立**:`$name` 可以是 `../../etc/hosts`,同样逃出工作区;
- 用「不可证但非无条件」的第三档(要求确认但可记住),需要先确认判档模型支持。

我倾向 1 先定方向再谈 2 —— 在没定之前不要按 PowerShell 那套直接套过去。

Contributor guide

Open the contributing guide

Research direction

Start with the tests for #2560 and the classifyShellCommand entry point mentioned in the issue. Compare the POSIX handling of dynamic write targets with the existing PowerShell behavior, then determine which policy choice is approved and add coverage for the listed commands; done means the chosen classification is explicit and the regression cases pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.