前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9375
  • Harness决定AI Agent能力:同模型不同表现
  • Claude Code权限绕过:Read拒绝后Bash仍可读取
  • 生产级Agent系统实战:LLM路由、Prompt合约与PR安全审查
  • LCLM:16倍压缩的潜在上下文语言模型
  • Claude Code mods解析:何时需要构建插件
  • Linus确认Linux内核进入「AI新常态」
  • 如何验证Agent实际完成了它声称的任务
  • Claude Code /compact 后哪些内容真正存活
  • 开源安全模型 apex-flash-1:60 个遗留 Bug 任务解出 40 个
  • yOGI Neural Grid:强制验证模型引用来源的工程实现
  • 美团开源LongCat-Video:13.6B参数统一视频生成模型
  • Agent技能需要包管理器而非仅靠Prompt
  • n8n AI Agent 生产环境失败根因与修复方案
  • 565 行 Python 从零实现编程智能体
  • 四大前沿模型横向评测:Astra擅计算机使用、Argon强法律金融、Sol价格最优
  • 本地RAG开发113个评估问题后的实战总结
  • AI重写让我重新审视运行时成本:Node.js转Go/Rust的算账
  • MCP工具超90个时的平台化架构设计
  • Homa:专为AI集群设计的TCP替代网络协议栈
  • 我为编码Agent的测试篡改问题做了个AdversaryGate
  • SaaS支持文档检索应选语义嵌入而非关键词
  • AI 审核员知道太多会变差:验证者应不知情
  • 长文档JSON提取超时?先做好输入分片而非调大timeout
  • PostgreSQL pgvector混合搜索实战:向量相似度+全文关键词融合
  • 新版Claude不再需要"Think Step by Step":Osmani提示指南解读
  • CodeSmith三区架构:解决prefix drift导致Token重计费问题
  • 像读流水线一样读Transformer Block
  • Cloudflare OS:面向 AI 原生的企业工作台开源
  • AI 编程工具正在泄露凭据:Cursor、Claude Code、Copilot 和 MCP 均有风险
  • prompt-shelf:在 Claude Code 里暂存草稿、临时想法和常用 prompt
  • Agenshive:AI agent 专属 Q&A 平台,用执行验证替代投票
  • 评审容量已成交付新瓶颈:打字快不等于交付快
  • 已加载 32 / 9375
8.0
热点
AI SCORE
技术实践2026-10-05 12:38

Claude Code权限绕过:Read拒绝后Bash仍可读取

dev.to · AI#Claude Code#安全#权限管理
Editor brief · 编辑速览

在Claude Code中将对.env文件的Read权限拒绝后,通过已授权的Bash命令(grep/cat)仍可读取敏感内容,权限规则按工具独立隔离。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

我把 .env 加到了拒绝列表里,觉得这样就万无一失了,然后回去继续工作。

一个小时后,我问 Claude Code 为什么测试运行器里 DATABASE_URL 是 undefined。它尝试用 Read 工具读取 .env,被拒绝了,说「我无法直接读取那个文件」,然后就在 Bash 里跑了 grep DATABASE_URL .env。几周前我就把 Bash(grep:*) 放进了允许列表,因为每次搜索都要点「是」太烦人了。我的生产连接字符串就这样在对话记录里滚过去了。

什么都没坏。Claude Code 的拒绝规则干的就是它们被设计来干的事。我只是误以为它们还能干别的事。

Claude Code 的拒绝规则是按工具划分的。Read(./.env) 阻断的是内置的 Read 工具。它挡不住 cat .env、grep KEY .env,或者通过 Bash 运行的 python -c "open('.env')"。

Bash 权限匹配的是命令字符串,不是文件。Bash 规则永远不知道一个命令会访问哪些文件。

路径语法也是个坑。权限规则里,/path 是相对于设置文件的路径,//path 才是绝对路径,而 ./.env 只匹配项目根目录的 .env。

修复要分层:正确设置文件工具的 glob、在 Bash 上加一个 PreToolUse hook 来拦截提及 .env 的命令、以及对于真正的密钥——别把它们放在 agent 工作目录里。

Claude Code 的拒绝规则到底能拦什么?

Claude Code 的拒绝规则阻止特定工具对特定目标执行操作。权限规则的形状是 Tool(specifier),而 specifier 对每个工具含义不同。

Read(...) 和 Edit(...) 接受文件路径模式,写法类似 gitignore。

Bash(...) 接受命令字符串模式,比如 Bash(npm run test:*)。

WebFetch(...) 接受域名,比如 WebFetch(domain:example.com)。

规则检查顺序是:先 deny,再 ask,最后 allow。所以同一个工具里 deny 永远优先于 allow。这一块运作正常。

关键在于「同一个工具」这几个字。Read 的拒绝规则是对 Read 工具的声明。它对 Bash 工具没有任何影响,而 Bash 运行的是任意程序,任意程序可以打开你用户账户能访问的任何文件。

为什么 Claude Code 能通过 Bash 读取我的 .env?

因为 Bash 是另一个工具,有另一套规则命名空间。当 Claude 运行 grep DATABASE_URL .env 时,Claude Code 是把你的命令字符串拿去和你的 Bash(...) 规则匹配的。你的 Read(./.env) 规则根本不会被查询。

我坐下来把 agent 读取文件的每种无聊方式都试了一遍,全部在一个项目里——Read(./.env) 被拒绝,常见的 Bash 命令被允许:

六种方式里只有一种会经过我写的规则。另外五种完全取决于我有没有仔细看每个 Bash 提示。当天下午批准到第四十个的时候,我已经不看了。

说句公道话,Claude 并没有在偷偷摸摸。它在调试,Read 工具失败了,而 grep 是一个模型回答我问题时的自然下一步。越过单个工具的失败正是你对一个 agent 的期望——直到那个文件是你的密钥。

Bash(cat .env) 这种 Bash 拒绝规则能解决问题吗?

不能。Bash 规则匹配的是命令文本,所以它只挡住一种写法,其他全都漏掉了。Bash(cat .env) 对以下情况毫无作用:

less .env
head .env
tail .env
awk 1 .env
while read l; do echo "$l"; done < .env
cd config && cat ../.env

Claude Code 文档自己就警告过,试图用 Bash 模式约束参数是脆弱的,并给了一个 curl URL 的例子——可以通过重新排列参数或使用变量来绕过。按拼写来拒绝文件名是同样的问题。你写的是你机器上每个程序的反向白名单。

Claude Code 权限规则用什么路径语法?

这是我的第二个错误,而且更隐蔽,因为规则看起来是对的。文件规则遵循 gitignore 风格的模式,有四种锚点:

如果你从终端复制一个绝对路径粘贴成 Read(/Users/me/app/.env),你写的是相对于设置文件所在位置的路径。看起来没问题但什么也匹配不到。

而 ./.env 只匹配根目录的文件。在一个存在 apps/api/.env 和 apps/web/.env.local 的 monorepo 里,这两个它都覆盖不到。你需要 ** 模式:

{
  "permissions": {
    "deny": [
      "Read(**/.env*)",
      "Edit(**/.env*)"
    ]
  }
}

这也会拦住 .env.example,通常没问题。如果需要让 .env.example 可读,Claude 仍然可以从你的配置加载器代码里获取变量名。

我怎样才能真正阻止 Claude Code 读取 .env 文件?

用三层。每一层覆盖前一层的漏洞。

第一层:正确设置文件工具的 glob。 就是上面的 JSON。这能拦住整个目录树下 Read 和 Edit 工具。

第二层:在 Bash 上加一个 PreToolUse hook。 Hook 在命令运行前看到完整命令,可以拦截它,而且它适用于你之前允许过的命令。把它保存为 .claude/hooks/block-env.sh 并 chmod +x:

#!/usr/bin/env bash
# Block Bash commands that mention a .env file.
cmd=$(jq -r '.tool_input.command // ""')

if printf '%s' "$cmd" | grep -Eq '(^|[^[:alnum:]_])\.env'; then
  echo "Blocked: this command touches a .env file. Ask the user for the specific value you need." >&2
  exit 2
fi
exit 0

然后在 .claude/settings.json 里注册:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-env.sh"
          }
        ]
      }
    ]
  }
}

这个正则能捕获 .env、./.env、../.env、.env.local 和 < .env,但不捕获 process.env,因为那前面是字母。stderr 消息会返回给 Claude,所以它通常会停下来问我而不是尝试第六种变体。那条消息是在干正事的。告诉模型该怎么做,而不只是说「不行」。

第三层:把真正的密钥放在够不着的地方。 这个 hook 是字符串匹配。cat .e""nv、base64 编码的文件名、或者内部加载 dotenv 的脚本都能绕过它。Claude 不会尝试这些,但字符串匹配不能保证它不会。所以对于真的会造成危害的凭证:

把生产值放在工作目录外面。使用密钥管理 CLI 在进程启动时注入变量,只把开发值留在仓库的 .env 里。

在从不挂载该文件的容器或 VM 里运行 agent。进程读不到不存在的东西。

我应该停止允许 grep 和 cat 这类 Bash 命令吗?

不一定,但要清楚你换来了什么。Bash(grep:*) 意思是「无需询问地 grep 任何东西、任何位置」,包括你的 home 目录、~/.aws/credentials 和 ~/.ssh。在一个沙盒化的边项目里这是合理的交换。在一个生产 .env 放在根目录的仓库里,这就不太好了。

我目前的设置:只在临时仓库里允许宽泛的 Bash 命令。在真实项目里,hook 是开着的,真正的密钥放在目录树外面,而且我会真的去看涉及点文件的提示。

Claude Code 的拒绝规则能保护我的 .env 文件吗?

部分能。Read(**/.env*) 这种 Claude Code 拒绝规则能阻止内置的 Read 和 Edit 工具,但它阻止不了 Bash,因为 Bash 权限匹配命令字符串,永远不知道一个命令会打开哪个文件。你批准过的或预先允许过的任何 cat、grep、head 或 python 命令仍然可以读取那个文件。还要检查你的路径锚点:/path 是相对于设置文件的,//path 才是绝对路径。要真正保护密钥,需要把文件工具的 ** glob 拒绝规则、Bash 上拦截提及 .env 命令的 PreToolUse hook、以及对于真正敏感的东西——把文件完全放在 agent 工作目录之外——这三层结合起来。


作者是 Preterview 的开发者,Preterview 是一个面试准备平台。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
Harness决定AI Agent能力:同模型不同表现
下一篇
生产级Agent系统实战:LLM路由、Prompt合约与PR安全审查