makecindy / makecindy/cindy

bug(macOS): iOS Simulator shell guard falsely blocks ordinary Python/Node heredoc commands

Open
#2,378 2 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.