Claude Code 实战-3.3 实现一个Hook

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,但同一模式可保护项目中的任意敏感文件或目录。你可以扩展逻辑以匹配多个文件模式,或基于安全需求实现更精细的访问控制。

发表回复