tools/safety: 新增 Tool 脚本安全防护机制#241
Conversation
|
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #241 +/- ##
==========================================
Coverage ? 88.32551%
==========================================
Files ? 492
Lines ? 46880
Branches ? 0
==========================================
Hits ? 41407
Misses ? 5473
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I have read the CLA Document and I hereby sign the CLA |
Invalidate ambiguous Python bindings, recognize builtins.open, and conservatively scan unknown execution tools. Remove unrequested design documents from the PR.
AI Code Review基于我对 发现的问题
|
AI Code Review确认: 我顺便确认一下 现在,我还需要确认是否存在针对 现在让我确认一下 env-prefixed 的情况是否真的只产生了 REVIEW 而不是 DENY——由于 但要注意:env-prefixed 模式与 实际上 让我完成最终报告。 发现的问题🚨 Critical
|
| if not tokens or os.path.basename(tokens[0]).lower() != "rm": | ||
| continue | ||
| options = [item for item in tokens[1:] if item.startswith("-")] | ||
| if any(item == "--recursive" or (not item.startswith("--") and "r" in item[1:]) for item in options): |
There was a problem hiding this comment.
递归删除检测漏掉 POSIX 大写 -R
_recursive_rm 用 "r" in item[1:] 判断递归标志且区分大小写,但 rm -R 是 POSIX 标准递归删除写法(GNU/BSD/macOS 均支持)。rm -Rf / 不会命中 FILE001(DENY),仅因 rm 不在允许命令列表产生 POLICY002(NEEDS_HUMAN_REVIEW),把本应 DENY 的递归删除降级为人工审核。建议改为 "r" in item[1:].lower() 或显式匹配 R。
AI Code Review没有 TODO。现在让我再次通过追踪带有 Python 让我来写最终的审查报告。 发现的问题🚨 Critical无。
|
AI Code ReviewI've read the full diff (5237 lines) and verified key downstream contracts ( 发现的问题
|
AI Code Review没有 发现的问题
|
AI Code Review确认: 我现在已经有了明确的审查结果。让我再检查一遍,确认 让我最后确认一下: 现在让我汇总最终的审查结果。让我写下来。 其实,让我重新考虑一下 然而,鉴于此防护明确侧重于递归/破坏性删除(FILE001 规范显示为“递归删除”),单文件删除可能超出了范围。但 让我最终确定我的审查结果:
让我合并或保留它们。它们是不同的规则和修复方法,所以我将分开列出。实际上两者都是 让我验证一下建议的数量 —— 最多 2 条。我将专注于此。 让我最后检查一下 现在让我写下审查报告。我已经完成了对 diff 的全面审查,并对照仓库上下文验证了被调用方( 发现的问题
|
AI Code Review我已经完成了彻底的审查。让我来写最终的审查结论。 发现的问题🚨 Critical
(经核对,
|
Normalize non-finite timeouts, serialize custom audit sinks, and expose a public output limiter so integrations avoid private APIs.
AI Code Review
让我更严谨地验证 让我再检查一下:超时后的 现在,一个真正的问题:在 让我再检查一下 让我重新考虑是否存在一个真正的严重问题。让我重新审视 等等——这里确实存在不一致。通过 filter 的 现在,关于 我已经有足够的内容来撰写审查报告了。让我整理一下发现的问题。让我做最后一次检查,看看 让我核实最后一个真正的问题: 现在让我写出审查报告。让我重新考虑最强有力的发现,并确保我没有捏造问题。让我核实一下 让我检查一个真实但细微的问题: 最后让我核实一下 现在,关于双重 让我再次思考 但我发现了一个真实的细微问题:在列表截断中, 现在确实存在一个 bug: 我现在对我的发现很有把握。让我定稿。让我再重新考虑一下示例 让我核实一下 README 中记录的退出码 "1=CLI/config error" 是否与 让我撰写最终的审查报告。让我重新考虑双重 实际上,让我重新考虑一个更具体、更站得住脚的问题。在 但是等等——真正的问题: 现在让我定稿。让我重新考虑是否有任何严重问题。让我再检查一遍 但注意:对于 Python, 我现在准备好写审查报告了。让我最终确定列表:
实际上,让我降低对该问题的断言程度并诚实表述。让我再找找是否还有更站得住脚的问题。 让我重新检查 现在,关于 我现在有信心了。让我定稿。让我重新考虑 让我写下审查报告。我已经审查了完整的 diff 以及相关的仓库上下文(filter runner、 发现的问题
|
Reap timed-out subprocesses without reusing canceled pipe readers, enforce output limits on timeout responses, and reduce shell keyword review noise.
AI Code Review
我现在已经进行了彻底的审查。该代码质量很高,且采用了故障安全(fail-safe)设计。让我确认最后几点——特别是 让我重新考虑一个真正的顾虑: 让我再重新考虑一下 根据我的审查,我将撰写审查意见。我能辩护的最具体的问题是:
让我重新考虑第 234 行: 老实说,这段代码经过了精心设计和测试。让我重新考虑是否有任何真正的问题,而不是强求。最合理的具体问题是:
鉴于进行了深入的审查且没有发现明确的 Bug,我应该报告“未发现明显阻塞问题”,并仅在有真正维护价值的情况下提出最多 1-2 条建议。让我确认在放弃之前没有漏掉真正的正确性/安全性 Bug。 让我仔细重新检查一个安全问题: 让我检查最后一件事 —— 如果满足两个条件, 我已经足够得出结论了。代码是稳健的。我将报告没有阻塞性问题,并提出 1-2 条可选建议。 让我快速验证一个真正的顾虑: 让我重新考虑 最终结论:没有明确的关键/警告级 Bug。我将记录下这些微小的可选建议。 发现的问题经逐文件审查 关键路径的 fail-safe 设计已落实到位,且可由现有测试验证:
💡 Suggestion
总结整体风险低,未发现必须修复的 Critical 或 Warning 级问题;安全扫描器在异常、审计失败、超时、脱敏等关键路径均按 fail-safe 设计并配有测试覆盖。两条 Suggestion 仅为可观测性与类型兼容性的可选改进。 测试建议暂无额外测试建议。现有测试已覆盖 deny/review/allow 决策、审计失败阻断、超时 clamp 与回写、并发审计写入、脱敏优先截断等高风险路径;如后续采纳上述 Suggestion,可补充「预算小于 marker_bytes 的列表截断仍可观测」与「省略 timeout 时回写类型符合目标工具 schema」两条用例。 |
Keep list truncation observable under tiny budgets and match integer timeout schemas when defaults are injected.
AI Code Review发现的问题🚨 Critical未发现 Critical 问题。所有安全关键路径(DENY 拦截、审计失败 fail-closed、超时注入与裁剪)均有对应测试覆盖,且在异常/降级路径上正确阻断执行。
|
Restrict newly created audit directories and continue scanning commands after shell control keywords.
- add visible truncation markers for string and list outputs - cover zero-budget truncation and os.open fail-closed behavior - harden JsonlAuditSink directory permissions and keep tests portable
AI Code Review发现的问题🚨 Critical无。
|
- replace literal_eval truthiness with structural checks - deny large repeated literal while conditions without allocation - make example acceptance import independent of cwd
AI Code Review
现在让我检查 我已有足够的信息来撰写审查报告。让我整理一下。 发现的问题🚨 Critical(无)
|
Prioritize formatted_output so BashTool responses cannot return oversized agent-facing output after stdout/stderr are clipped.
AI Code ReviewI have completed a thorough review of the diff. Below are my findings. 发现的问题🚨 Critical未发现 Critical 级别问题。
|
- truncate all string fields in tool output dicts - treat numeric multiplication in loop conditions as static truthy - avoid chmodding cwd for plain relative audit paths
AI Code ReviewBash 环境需要批准,且无法运行 Python。我已经从 现在我有足够的上下文了。让我基于已知信息完成审查。我将跳过 Python 执行验证,仅依赖静态阅读。 发现的问题🚨 Critical
|
| delegate: BaseCodeExecutor | ||
| guard: Any | ||
| audit_sink: Any | ||
|
|
There was a problem hiding this comment.
审计失败路径异常文本未脱敏进入结构化报告
error_report 构造阻断报告时,make_finding 对异常对象调用 sanitize(error),但 str(error) 可能含原始异常消息(如 sink 抛出的 OSError 文本),作为 evidence 暴露给调用方。建议对 evidence 同样走 sanitizer 并避免回显原始异常消息。
- avoid leaking audit exception text in safety reports - preserve timeout_sec float injection for workspace tools - drain MCP subprocess output after timeout - simplify audit directory permission handling
Ensure newly created audit parent directories are tightened to 0700 again while keeping plain relative paths from chmodding cwd.
AI Code Review发现的问题
|
AI Code Review
我已经有足够的上下文来编写审查报告。让我整理一下我的发现: 可验证的问题:
让我重新考虑一下是否真的存在关键问题。让我再检查一件事—— 让我再检查一下:在 现在看一个真正值得关注的问题:子进程超时使用了 让我确认一下没有明显的 bug,并写审查报告。再快速检查一下 现在让我检查 让我再看一个: 我认为没有关键问题了。让我把双重否定问题写成警告,或许再加一条关于 sanitizer 的建议。其实,让我再核实一下双重否定是否真的可被利用且足够常见: 让我再核实一下 现在让我再考虑一下 所以只有双重否定(以及更深的嵌套)会漏掉。这是一个真实的、尽管范围有限的绕过。我会将其标记为警告。 让我再核实一个可验证的 bug:在 我已经可以下结论了。让我写审查报告。鉴于可验证的问题有限,双重否定是唯一真正值得注意的发现。让我看看还有没有更具体的。 其实,让我重新检查 让我最终定稿。我会保持简洁。 再次检查:示例中的 最终答案。我会将双重否定标记为警告,并添加一条关于测试预期与 让我重新考虑严重程度:双重否定绕过——安全工具漏掉无限循环是功能上的漏洞,但由于文档说明静态分析不是沙箱,所以是警告。我就定这个。 再重新考虑一下:是否有任何关键问题? 没有关键问题。写审查报告。我已经完整审阅了 发现的问题
|
AI Code Review我现在已经完全理解了。让我来撰写最终的评审意见。 发现的问题🚨 Critical未发现 Critical 级别问题。
|
AI Code Review合成构件,无敏感信息。很好。 现在让我重新考虑 现在让我再核实一下关于审计 让我重新考虑 现在让我检查最后一个真正值得关注的问题: 我已经完成了全面的审查。代码质量很高,采用了故障安全(fails-closed)设计,且测试充分。我真正想要提出的问题: 让我再次确认问题 A —— 仔细检查 让我再核实一下 鉴于指令要求不要编造低价值的建议,且代码确实稳健,我将提供一个聚焦的审查。让我重新考虑一下 所以甚至问题 A 的漏洞也仅限于扫描器未检测到的机密(罕见)。我将如实记录:未发现关键/阻塞性问题,并提供真正值得注意的少量观察结果。 让我再仔细核实一个我想要确定的真正候选问题: 我现在对我的审查结果充满信心。代码很稳健。让我撰写最终的审查意见,并附上真正的观察结果。 让我最后核实一个潜在的实际 Bug: 让我核实一下 一切都已验证且稳健。代码库通过了彻底的审查。我将提供一份重点突出的审查意见,包含真正有价值的观察结果。 基于我对整个 PR 的彻底审查,代码质量很高,采用了故障安全(fails-closed)的设计,并且经过了充分测试。以下是我的审查意见: 发现的问题
|
AI Code Review我已经确认了关键细节。让我再确认一下 现在,最后一个需要验证的真正关注点:关于 我现在非常确定。让我写下审查意见。我会将 让我再重新考虑一下是否还有我遗漏的真正 Critical 问题——带有攻击者控制路径的 再看一个: 我准备好撰写审查意见了。再重新考虑一下 现在让我写下最终的审查意见。基于我对 发现的问题
|
AI Code Review发现的问题
|
AI Code Review基于我对完整 diff 的审查,我的审查结论如下。 发现的问题
|
Tool、Skill、MCP Tool 和 CodeExecutor 在执行脚本时,可能产生危险文件操作、非预期网络访问、凭据泄漏、依赖环境变更和资源滥用等安全风险。
本次变更新增可选、策略驱动的 Tool Script Safety Guard,在 Python 脚本和 Bash 命令真正执行前完成静态扫描,并输出 allow、deny 或 needs_human_review 决策。
安全检查器覆盖危险文件操作、非白名单网络外连、进程和 Shell 命令、依赖安装、资源滥用以及敏感信息泄漏。用户可以通过 YAML 策略配置白名单域名、允许命令、禁止路径、最大执行超时和最大输出大小,无需修改代码。
本次变更提供 Tool Filter、Skill 和 MCP adapter,以及 CodeExecutor wrapper。被拒绝的执行会返回结构化报告并记录可审计事件;启用 OpenTelemetry 时,还会写入对应的安全 span attributes。
示例目录提供 12 个可独立扫描的安全、危险和人工复核样本。文档说明了规则体系、接入方式、扩展方法、误报、漏报、绕过风险,以及该机制不能替代沙箱隔离的原因。
已在 Python 3.12 Docker 环境完成验证:134 个安全测试全部通过,安全模块覆盖率为 94.28%,YAPF 和 flake8 检查通过。验收测试确认 12 个公开样本决策全部正确,三类强制风险检出率为 100%,安全样本误报率为 0%,500 行脚本扫描耗时小于 1 秒。
实现全部通过新增文件完成,不修改现有 FilterRunner 或其他核心执行文件。
Fixes #90
RELEASE NOTES: 新增可配置的脚本执行前安全检查、风险拦截和审计能力。