bug(macOS): iOS Simulator shell guard falsely blocks ordinary Python/Node heredoc commands
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 401
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
**客户端版本**: 0.1.43
**反馈类型**: bug
---
## 现象
桌面端执行普通本地 shell 命令时,偶发收到:
`Cindy blocked a shell command that would bypass the embedded iOS Simulator...`
被拦截的命令是 Python/Node heredoc 脚本,用于依赖探测、图标生成、文档检查和日志分析;没有启动 Simulator.app、调用 `xcrun simctl),也没有执行 iOS 设备操作。同一 Codex 会话约一小时内观测到 7 次拦截。
## 复现步骤
下面是根据已观测命令和当前源码缩小出的最小复现候选;尚未在全新会话中单独验证其确定性:
```sh
python3 - <<'PY'
import json
__import__("json")
print(json.dumps({"ok": True}))
PY
```
1. 在 macOS 桌面端启动 Codex 会话。
2. 执行上面的普通 Python heredoc 命令,或执行包含 `ET.fromstring(...)`、`})().catch(...)` 等普通解释器代码的 Python/Node heredoc。
3. 观察命令被 host policy 拦截;命令没有执行。
## 期望行为
只应拒绝真正绕过 Cindy 模拟器托管边界的命令,例如可执行的 `xcrun simctl` 变更操作或 `open -a Simulator)。普通解释器 heredoc 应继续进入正常权限流程并执行。
## 实际行为
策略先识别 heredoc,但随后又在 `containsSimulatorBypass` 的主循环中把 heredoc 的每一行按 shell 可执行段重新解析。Python 的 `__import__("json")`、`ET.fromstring(...)` 和 Node 的 `})().catch(...)` 会被当成包含动态括号的可执行文件,触发 fail-closed 分支 `hasUnresolvedExecutableExpansion`,即使正文没有任何 simulator token。
host 端随后中断 turn;Codex 审批通道关闭后又显示二次错误 `approval request aborted`,使任务在中途结束。
源码定位:
- [heredoc 识别](https://github.com/makecindy/cindy/blob/c29724bcc4c1b73ea7155a1aa4d7d1112f0adffc/apps/desktop/src/main/maker-host/shell-command-policy.ts#L1075-L1095)
- [逐行重新按 shell 解析并 fail-closed](https://github.com/makecindy/cindy/blob/c29724bcc4c1b73ea7155a1aa4d7d1112f0adffc/apps/desktop/src/main/maker-host/shell-command-policy.ts#L1271-L1311)
- [策略接入 Codex](https://github.com/makecindy/cindy/blob/c29724bcc4c1b73ea7155a1aa4d7d1112f0adffc/apps/desktop/src/main/maker-host/index.ts#L1114-L1120)
## 复现频率
- 已观测:同一会话约一小时内 7 次。
- 是否在全新会话中稳定复现:未知。
- 是否与具体模型或工作目录有关:未知。
## 已尝试
继续发送普通任务并重试命令;每次被拦截的命令都没有使用模拟器能力。问题发生后,相关任务无法继续完成。
## 建议
1. 解析 heredoc 时只扫描其正文中的 simulator 执行器字面量,不要把解释器代码逐行当作 shell 命令。
2. 为 Python、Node 等安全 heredoc 增加放行回归测试;当前测试主要覆盖应拒绝的模拟器命令。
3. host guard 的拒绝应与 Codex 的 `approval request aborted` 分开报告,并避免无关命令导致整个 turn 失去恢复机会。
4. 记录不含命令正文的规则 ID/分类,便于区分真正的 Simulator bypass 与误判。
---
**OS**: darwin arm64 (25.6.0)
**界面语言**: zh-CN
Contributor guide
Research direction
Start in apps/desktop/src/main/maker-host/shell-command-policy.ts at the heredoc handling around lines 1075-1095 and the fail-closed loop around lines 1271-1311. Reproduce with the Python heredoc and inspect the Codex integration in apps/desktop/src/main/maker-host/index.ts around lines 1114-1120. Done means safe Python and Node heredocs avoid simulator-bypass rejection while genuine simulator commands remain blocked, with regression coverage added.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, python, typescript
- Domain
- desktop, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100