3.3 实现一个Hook
让我们构建一个自定义 Hook,阻止 Claude 读取敏感文件(如 .env)。这是利用 Hooks 在开发会话中保护环境变量与机密数据的实用示例。
一、配置 Hook
首先在设置文件中配置 Hook。打开 .claude/settings.local.json,找到 hooks 区域。因为需要在执行前拦截工具调用,我们创建一个 PreToolUse 类型的 Hook。
该配置包含两部分关键内容:
1. Matcher:指定要监听的工具类型。
2. Command:当这些工具被调用时运行的脚本。
针对可能访问 .env 的读取与搜索操作,匹配器为:
“matcher”: “Read|Grep”
竖线(|)充当 OR 操作符,表示 Read 或 Grep 均会触发。命令指向一个 Node.js 脚本:
“command”: “node ./hooks/read_hook.js”
二、了解工具调用数据
当 Claude 尝试使用某个工具时,你的 Hook 会通过标准输入接收该调用的详细 JSON 数据,包括:
1.会话 ID 与对话记录路径
2.Hook 事件名(此处为 PreToolUse)
3.工具名称(如 Read、Grep)
4.工具输入参数(含文件路径)
你的脚本解析这些数据,并通过退出码决定放行或阻止该操作。
三、编写 Hook 脚本
脚本需要从标准输入读取工具调用数据,判断 Claude 是否试图访问 .env 文件。核心逻辑如下:
async function main() {
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
const toolArgs = JSON.parse(Buffer.concat(chunks).toString());
// 提取 Claude 想读取的文件路径
const readPath =
toolArgs.tool_input?.file_path || toolArgs.tool_input?.path || “”;
// 检查是否读取 .env 文件
if (readPath.includes(‘.env’)) {
console.error(“You cannot read the .env file”);
process.exit(2);
}
}
当检测到路径包含 .env 时,脚本通过退出码 2 阻止操作,并向标准错误输出信息。Claude 会理解该操作被 Hook 拦截并给出解释。
四、测试 Hook
保存配置与脚本后,重启 Claude Code 以使更改生效。随后让 Claude 尝试读取你的 .env 文件进行测试。
当 Claude 发起读取操作时,Hook 会拦截并返回错误信息。Claude 会识别到操作被阻止,并说明是读取 Hook 阻止了访问。同样,对 Grep 搜索 .env 的操作也会被阻止。
五、关键收益
1. 主动防护:在敏感数据被读取前即拦截。
2. 透明反馈:Claude 明确知道失败原因。
3. 灵活匹配:可同时作用于 Read、Grep 等多种工具。
4.清晰提示:提供有意义的错误信息。
此示例聚焦 .env,但同一模式可保护项目中的任意敏感文件或目录。你可以扩展逻辑以匹配多个文件模式,或基于安全需求实现更精细的访问控制。