Exec 安全模型

wesgine 的 exec 工具执行外部命令时的安全约束与保护机制。


治理链集成

exec 工具调用经过完整的治理管线(Governance Pipeline):

Hardline 检查

18 条灾难命令正则,不可覆盖:

Sandbox 检查

网络命令检测(INV-GOV-02)

NetworkPolicy=deny 或 internal_only 时:

检测目标位置
curl / wget命令位置(行首 / 分隔符后)
nc / ncat / netcat引号与子 shell 内
ssh / scp / sftpsudo/env 等 wrapper 后
rsync可选路径前缀后

参数位置的同名词不误杀(如 grep -r curl .)。


进程组管理(INV-EXEC-PROC-01)

所有 exec 通过 proc.Command(ctx, ...) 创建子进程:

proc.Command
  ├── Setpgid = true        ← 建进程组
  ├── Cancel = SIGKILL 整组  ← cancel 时杀全组
  └── WaitDelay = 超时       ← Wait 不无限挂

超时后清理(INV-EXEC-11)

ctx 结束后调用 KillProcessGroup() 清理整个进程组,防止逃逸的 grandchild 存活。

stdout 排空(INV-EXEC-12)

进程退出后 stdout 排空最多等 5s,超时强制 CloseOutput()。


输出读取(INV-EXEC-DRAIN-01)

禁止 bufio.Scanner 读取命令输出。

原因:Scanner 的 max-token 限制(1MB)遇到无换行大输出时提前退出读循环 → 管道无人消费 → 子进程阻塞 → cmd.Wait() 永不返回(死锁)。

正确做法:

ReadSlice 循环(64KB 块)
  ↓ 缓冲满继续读
cappedWriter 限内存
  ↓ 超内存上限截断
io.Copy(io.Discard, ...) 排空剩余
  ↓
cmd.Wait()

环境变量隔离

exec 子进程与引擎同 UID,凭据不进子进程靠 SanitizeEnv 两层:

静态模式表(INV-SEC-04)

已知的敏感环境变量模式:

SecretRef 变量名登记(INV-SEC-03)

SecretRef{source:env} 的变量名显式登记到清洗列表。

不是猜命名,是登记——知道的才清。


CWD 优先级(INV-IO-03)

exec 的工作目录优先级:

显式 cwd 参数
  ↓ 未指定
PrimaryRoot(agent 主工作上下文)
  ↓ 未指定
ScratchDir
  ↓ 未指定
ArtifactDir

编程场景下 PrimaryRoot = VS Code 项目根。


exec 路由(wescode 特有)

wescode 对 exec 做三分类路由:

分类路由用户可见典型命令
检索/探索Go os/exec不可见rg, git status, ls
验证/构建Go os/exec + mirror只读终端go build, npm test
服务/交互VSCode 集成终端用户终端npm start, docker compose up

Zone 分类

exec 工具在治理链中的 Zone 分类:

操作Zone
只读命令(ls, cat, grep)Green
一般命令Yellow
delegate_taskRed(INV-GOV-03)

Yellow Zone 行为由 GovernMode 决定:


前台超时

前台 exec 使用 context deadline:

ctx 设置超时
  ↓ 超时到达
KillProcessGroup()     ← 杀整个进程组
  ↓ 等 5s
CloseOutput()          ← 强制关管道

相关文档