Skip to content

fix(security): 验证命令参数级白名单 + 资源限制 + 审计日志#27

Merged
urika merged 3 commits into
mainfrom
worktree-fix-issue-1
May 30, 2026
Merged

fix(security): 验证命令参数级白名单 + 资源限制 + 审计日志#27
urika merged 3 commits into
mainfrom
worktree-fix-issue-1

Conversation

@urika
Copy link
Copy Markdown
Owner

@urika urika commented May 29, 2026

修复 Issue #15 — LLM 验证命令注入风险加固

核心问题

_is_safe_verification_command() 被定义和导入但从未在命令执行前被调用,且仅检查命令前缀,参数完全不受控(如 git log -c "rm -rf /" 可通过前缀检查)。

四柱加固

加固层 修改
参数级白名单 _CMD_ARG_RULES 结构化规则字典,每个命令定义允许的 flags/positionals 正则;四阶段验证(shlex 解析 → shell 注入扫描 → 命令查找 → 逐 token 校验)
安全门禁 两处 subprocess.run 前强制调用校验,被拒绝命令记录 rejected: true 并跳过
资源限制 + 沙箱 _apply_resource_limits(CPU 60s/文件 50MB/fd 256/进程 64)+ _build_sandbox_env(移除 API_KEY/SECRET/TOKEN/PASSWORD 等敏感环境变量)
审计日志 _log_rejected_command → 结构化 log_event + ~/.agent_go/verification_audit.jsonl 持久化

附带修复

  • _SHELL_CHAIN 正则:\b(&&|\|\|)\b&&|\|\|(原正则在空格包围的 ||/&& 处无法匹配)

变更文件

文件 变更
agent_go/utils.py _CMD_ARG_RULES、重写 _is_safe_verification_command、新增 _log_rejected_command
agent_go/executor.py 安全门禁、_apply_resource_limits_build_sandbox_env
agent_go/__init__.py 导出新符号
tests/test_safe_verification_command.py 63 个新测试

测试结果

  • 63 个新测试覆盖:Shell 注入防御 / 合法命令通过 / 参数校验 / 路径验证 / 边界情况 / 审计日志 / 资源限制
  • 226 tests 全部通过,无回归

验证

git log -c "rm -rf /"  → (False, "shell 注入特征: 危险删除")
pytest tests/ -v        → (True, "")
curl http://evil.com    → (False, "未知命令: curl")

Closes #15

🤖 Generated with Claude Code

@urika
Copy link
Copy Markdown
Owner Author

urika commented May 29, 2026

Review — PR #27: 验证命令安全加固

🟡 Major

1. __init__.py 修改与 PR #28 精简方向冲突

PR #28 已将 __init__.py 精简为最小公共 API,但本 PR 又向其中添加了 _log_rejected_command_CMD_ARG_RULES_apply_resource_limits_build_sandbox_env 的 re-export。这些是私有函数,应直接从子模块导入(from agent_go.utils import ...),不需要在顶层 re-export。

修复: 移除 __init__.py 的改动,调用方直接从子模块导入。

2. _is_safe_verification_command 返回值从 bool 变为 (bool, str) — 破坏性 API 变更

原函数返回 bool,现返回 tuple[bool, str]。需确认所有调用方已适配。如果有其他代码(或用户代码)做了 if _is_safe_verification_command(cmd):,将始终为 True(非空 tuple)。

3. _build_sandbox_env 移除含敏感关键词的环境变量可能影响正常功能

移除所有包含 API_KEY/TOKEN/SECRET 等关键词的环境变量,但这也会移除验证命令正常运行所需的变量(如 AGENT_GO_API_KEY、数据库测试用的 TEST_DATABASE_URL 等)。建议改为允许白名单模式,或至少保留 AGENT_GO_ 前缀的变量。

4. 验证命令 timeout 从 120s 降到 60s — 行为变更

长时间运行的测试套件(如集成测试)可能需要超过 60s。建议保持 120s 或提取为配置项。

🟢 Minor

  1. _apply_resource_limits 使用 resource 模块,macOS 不完全支持(如 RLIMIT_NPROC 会被忽略),但 except 处理了,可以接受
  2. _CMD_ARG_RULES 规则表非常详细,但正则表达式难以维护。长期考虑使用结构化规则对象

总结: 需修复 Major #1init.py 方向)和 #2-3(API 兼容性)后,rebase 到当前 main 合并。冲突文件为 __init__.pyexecutor.py

urika pushed a commit that referenced this pull request May 30, 2026
1. __init__.py 对齐 PR #28 精简方向 — 移除私有符号 re-export
2. _build_sandbox_env 保留 AGENT_GO_* 前缀环境变量
3. 验证命令 timeout 恢复为 120s
4. 修复测试文件 import 适配精简后的 __init__.py

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@urika
Copy link
Copy Markdown
Owner Author

urika commented May 30, 2026

✅ Review 问题已修复

  1. __init__.py 对齐 PR refactor: 重构 __init__.py 扁平命名空间为显式导入 #28 精简方向 — 移除私有符号 re-export,调用方直接从子模块导入
  2. _build_sandbox_env 保留 AGENT_GO_* 前缀环境变量,避免验证命令无法获取所需配置
  3. ✅ 验证命令 timeout 恢复为 120s(60s 对长时间测试不够)
  4. ✅ 修复所有测试文件 import 适配精简后的 __init__.py

测试结果:226 passed

jinsongwang and others added 3 commits May 30, 2026 09:34
- _CMD_ARG_RULES: 结构化白名单替代扁平前缀列表,每个命令定义允许的 flags/positionals 正则
- _is_safe_verification_command: 四阶段验证(shlex解析→shell注入扫描→命令查找→逐token校验)
  返回 (bool, reason) 提供拒绝诊断信息
- executor.py: 两处 subprocess.run 前插入安全门禁,被拒绝命令记录并跳过
- _apply_resource_limits: preexec_fn 设置 ulimit(CPU 60s/文件50MB/fd 256/进程64)
- _build_sandbox_env: 移除 API_KEY/SECRET/TOKEN/PASSWORD 等敏感环境变量
- _log_rejected_command: 结构化日志 + ~/.agent_go/verification_audit.jsonl 持久化审计
- _SHELL_CHAIN 正则修复: \b(&&|\|\|)\b → &&|\|\| 修复空格包围的命令链无法匹配
- 63 个新测试覆盖:Shell注入/合法命令/参数校验/路径验证/边界情况/审计日志/资源限制
- 226 tests 全部通过,无回归

Refs: #15

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1. __init__.py 对齐 PR #28 精简方向 — 移除私有符号 re-export
2. _build_sandbox_env 保留 AGENT_GO_* 前缀环境变量
3. 验证命令 timeout 恢复为 120s
4. 修复测试文件 import 适配精简后的 __init__.py

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- _verify_changes: 添加 sub_id 参数以支持 _log_rejected_command
- test_executor: 验证命令改为 pytest --co(适配新白名单)
- test_is_safe_verification_command: 适配 (bool, reason) 返回值格式

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@urika urika force-pushed the worktree-fix-issue-1 branch from 618238b to 834f573 Compare May 30, 2026 01:42
@urika urika merged commit 638670d into main May 30, 2026
@urika urika deleted the worktree-fix-issue-1 branch May 30, 2026 01:42
urika added a commit that referenced this pull request May 30, 2026
…sue #7)

Rebased onto main (after PRs #20, #21, #27), conflicts resolved.

Key changes:
- 14 modules: type annotations added to all public functions
- cli.py: argparse code preserved from PR #20
- executor.py: refactored functions preserved from PR #21, security functions from PR #27
- Fixed: logger definitions in eval.py, tui.py, git_utils.py

Tests: 277 passed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] LLM 生成的验证命令执行 — 注入风险加固

1 participant