新闻详情

新闻详情

首页 / 资讯中心 / 详情

51万行代码一夜暴露:Claude Code 的 source map 为何成了安全筛子?

发布时间:2026/9/27 20:01:35来源:尧图网络
51万行代码一夜暴露:Claude Code 的 source map 为何成了安全筛子?
1. 一次 npm 发布为什么能把 51 万行 TypeScript 源码端上桌Claude Code 的 source map 泄露事件本质不是“黑客攻破”而是构建产物里混进了不该发布的调试文件。npm 包一旦带上cli.js.map任何人都能用source-map工具把压缩后的 JS 还原成接近原始的 TypeScript。这次泄露的文件约 59.8MB解压后对应 1900 多个.ts源文件、51.2 万行代码核心引擎、工具权限、未发布特性标志全部可读。source map 是什么你可以把它理解成“压缩代码的翻译字典”。生产环境为了减小体积会把变量名压成a、b把换行去掉source map 记录的就是“第 3 行第 15 列的a原本叫queryEngine”。它本身是给调试用的浏览器 DevTools 能靠它显示原始源码。问题在于调试用的字典不该跟着发布包一起发给全世界。这件事对普通开发者的价值不在于围观而在于自查。你我的项目大概率没有 51 万行但只要用 TypeScript 打包器 npm 发布就可能踩同一个坑。下面我会把泄露链路拆开给出可复制的排查命令、发布前剥离配置以及 CI 里能卡住问题的验证动作。适合谁看用 npm 发包的前端/Node 开发者、维护 CLI 工具的团队、在 CI 里做产物审计的工程同学。读完你能回答三个问题——我的包里有没有 map、怎么在发布前剥掉、怎么在 CI 里自动拦住。2. 泄露链路还原Bun 打包 npm 发布 存储桶直读2.1 从源码到公网的三步Claude Code 用 Bun 作为运行时和打包器。Bun 的build默认可以生成 source map配置项是--sourcemap取值有none、linked、inline、external。如果构建脚本里写了--sourcemapexternal就会在输出目录旁边生成cli.js.map并在cli.js末尾加一行注释//# sourceMappingURLcli.js.map发布环节如果package.json的files字段或.npmignore没有排除*.map这个文件就会被打进 tarball。npm 的默认行为是没有.npmignore时用.gitignore两者都没有则几乎全发。很多团队以为.gitignore写了*.map就安全但 npm 的规则和 git 不完全一致这是第一个常见误区。第三步是分发。npm 包的 tarball 存在 CDN/对象存储上任何人npm pack或直接拼 URL 都能下载。source map 一旦在里面还原源码只需要一条命令。2.2 还原有多简单拿到cli.js和cli.js.map后用source-map库或现成 CLI 就能批量还原npm i -g source-map-cli source-map resolve cli.js.map 123 45更彻底的做法是用shuji或自己写脚本遍历sourcesContent字段——很多打包器会把原始源码直接内联进 map 的sourcesContent数组连反查都省了。这就是为什么泄露能在一夜之间产出完整可读的代码库。注意sourcesContent内联是默认行为之一。即使 map 文件本身没被下载只要它进了包源码就等于公开。3. 发布前自查三条命令确认产物里有没有 map在讲剥离配置之前先学会“验尸”。以下命令在你的项目根目录执行发布前跑一遍。3.1 看构建输出目录find dist build out -type f -name *.map 2/dev/null有输出就说明构建阶段生成了 map。如果这是生产构建需要确认是否该保留。3.2 看 npm 包实际会带什么这是最关键的一条。npm pack --dry-run会列出即将发布的文件清单不真正打包npm pack --dry-run 21 | grep -E \.map$|sourceMappingURL如果看到.map结尾的行说明它会被发布。再检查 JS 文件里有没有残留的 sourceMappingURL 注释grep -rn sourceMappingURL dist/ 2/dev/null3.3 直接检查已发布的包对已经发出去的版本可以下载 tarball 检查npm pack your-package1.2.3 tar -tzf your-package-1.2.3.tgz | grep \.map$有输出就说明线上包带 map。这时候要评估是发个 patch 版本修掉还是把该版本npm deprecate掉。4. 可复制的剥离配置Bun、tsc、npm 三处都要管排查只是发现配置才是根治。source map 泄露通常有三个入口要逐个堵。4.1 Bun 构建关闭 external map如果构建脚本里有--sourcemapexternal生产构建改成none{ scripts: { build: bun build src/cli.ts --targetnode --outdirdist --sourcemapnone, build:debug: bun build src/cli.ts --targetnode --outdirdist --sourcemapexternal } }保留一个build:debug给本地调试用生产走none。这样从源头就不生成 map。4.2 tsc 的 sourceMap 与 declarationMap如果用tsc编译检查tsconfig.json{ compilerOptions: { sourceMap: false, declarationMap: false, inlineSourceMap: false, inlineSources: false } }declarationMap容易被忽略——它给.d.ts生成 map同样会暴露类型源码结构。生产构建建议全部关掉。4.3 npm 发布白名单用 files 而不是 ignore比.npmignore更可靠的是package.json的files白名单。只声明要发布的目录其余一律不发{ files: [ dist/**/*.js, dist/**/*.d.ts, !dist/**/*.map, README.md, LICENSE ] }files支持!排除语法。注意files的匹配是在打包阶段生效的比.npmignore优先级更高、更不容易出错。如果团队坚持用.npmignore至少写上*.map **/*.map *.ts !*.d.ts提示.npmignore存在时.gitignore会被忽略。两者规则不一致是很多“明明 git 里没提交却发出去”的根因。5. CI 验证让流水线在发布前拦住 map配置靠人记CI 靠机器卡。在发布 job 里加一步产物审计不通过就 fail。5.1 一个可用的检查脚本#!/usr/bin/env bash set -euo pipefail echo 检查构建产物中的 source map if find dist -type f -name *.map | grep -q .; then echo ERROR: dist 中发现 .map 文件禁止发布 find dist -type f -name *.map exit 1 fi echo 检查 JS 中的 sourceMappingURL if grep -rn sourceMappingURL dist --include*.js | grep -q .; then echo ERROR: 产物中存在 sourceMappingURL 注释 grep -rn sourceMappingURL dist --include*.js exit 1 fi echo 检查 npm 实际发布清单 if npm pack --dry-run 21 | grep -E \.map$ | grep -q .; then echo ERROR: npm 发布清单包含 .map 文件 npm pack --dry-run 21 | grep -E \.map$ exit 1 fi echo 产物审计通过5.2 接进 GitHub Actionsname: release on: push: tags: [v*] jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-nodev4 with: node-version: 20 registry-url: https://registry.npmjs.org - run: npm ci - run: npm run build - run: bash scripts/audit-artifacts.sh - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}关键是audit-artifacts.sh放在npm publish之前。审计不过发布步骤根本不会执行。5.3 用 TaoToken 做发布前的模型辅助审查如果团队已经在用大模型做代码审查可以把产物审计的日志喂给模型做二次判断。TaoToken 提供统一的 API 入口模型对话入口在 模型对话接入文档在 接入文档。比如把npm pack --dry-run的输出贴进去让模型判断有没有可疑文件类型curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [ {role: user, content: 以下是 npm pack --dry-run 的输出请找出可能泄露源码的文件\n粘贴输出} ] }API Key 在 API Keys 页面创建。这一步是锦上添花核心还是前面的脚本硬卡。6. 本篇常见错排查6.1 关了 sourceMap 但包里还有 map大概率是依赖的构建工具或某个子包自己生成了 map。用npm pack --dry-run看具体路径定位到是哪个 workspace 或哪个依赖的产物。monorepo 里尤其常见——根包关了子包没关。6.2 .npmignore 写了 *.map 却没用检查是不是同时存在.gitignore和.npmignore且.npmignore里没有覆盖到子目录。*.map只匹配当前目录子目录要用**/*.map。更稳的方案是改用files白名单。6.3 CI 里 npm pack --dry-run 输出格式不稳定不同 npm 版本输出格式有差异grep 可能误判。建议用npm pack --json --dry-run拿结构化输出再用jq解析npm pack --json --dry-run | jq -r .[0].files[].path | grep \.map$6.4 已经发布了带 map 的版本怎么办先发 patch 版本修掉然后对旧版本执行npm deprecate your-package1.2.3 contains source map, please upgrade。如果包是私有的联系 registry 管理员看能否下架。公开包一旦发布被镜像和缓存是常态下架不等于消失。6.5 Bun 的 --sourcemap 参数写错Bun 的取值是none/linked/inline/external不是布尔值。写--sourcemapfalse可能不生效。确认构建命令和 Bun 版本文档一致。7. 把审计变成习惯接入与长期编码的入口这次事件最值得记住的一点能做出六层权限系统的团队也会在.npmignore上翻车。安全不是靠某个环节的聪明而是靠每个环节的笨功夫——构建关 map、发布走白名单、CI 卡产物三步缺一不可。如果你在团队里负责发布流程建议把第 5 节的审计脚本直接进仓库作为发布 job 的强制门禁。需要长期跑编码 Agent、把这类审计脚本自动生成和维护的可以看 Coding Plan需要管理多个项目的 Key 和用量在 Console 里配置。Claude Code 相关的接入细节在 ClaudeCodeAnthropic 有说明。最后留一个可以立刻做的动作打开你最近发布的一个 npm 包跑一遍npm pack --dry-run | grep \.map$。有输出的话今天就发个 patch。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

网站推广对接图解步骤:新手避坑全记录 2026/9/27 20:49:27

网站推广对接图解步骤:新手避坑全记录

网站推广对接图解步骤:新手避坑全记录 手里攥着预算,心里没底?很多刚入行做网站的朋友,甚至包括那些想自己搞个展示站的外行,最头疼的就是 网站推广对接…

阅读更多 →
LVGL v8.0+嵌入式UI动画卡顿优化:七个实战技巧提升帧率 2026/9/27 20:49:21

LVGL v8.0+嵌入式UI动画卡顿优化:七个实战技巧提升帧率

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
电动汽车充电站规划:出行链、马尔科夫链与排队论实战 2026/9/27 20:49:21

电动汽车充电站规划:出行链、马尔科夫链与排队论实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
ADV7513BSWZ HDMI发送器配置实战:从寄存器到Linux驱动调试指南 2026/9/27 20:49:21

ADV7513BSWZ HDMI发送器配置实战:从寄存器到Linux驱动调试指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
USB设备偶发断连与识别不到:枚举、供电到抓包的排查实战 2026/9/27 20:49:21

USB设备偶发断连与识别不到:枚举、供电到抓包的排查实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
洗碗机水泵EMC整改实战:高集成驱动方案从超标到过审 2026/9/27 20:49:21

洗碗机水泵EMC整改实战:高集成驱动方案从超标到过审

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉