npx afterpack@latest audit <url> 会抓取网站发布的 JavaScript,并报告读者能从中提取出什么。它与公开的安全扫描器是同一个扫描器:公开的 source map、你自己代码的可读程度、泄露的凭据,以及不计分的第三方代码、动态代码注入点和检测到的技术栈。
audit 是只读的。它不会修改任何内容,不需要账户,只接触该 URL 公开提供的内容。
运行
$ npx afterpack@latest audit https://yoursite.com协议前缀是可选的:裸主机名会被规范化为 https://。扫描器会抓取页面并渲染它,以便包含客户端加载的代码包,然后分析找到的每一个 JavaScript 资源。
没有本地目录模式。不支持 npx afterpack@latest audit ./dist。参数必须是一个 URL。请改为审计一个预览部署。
它检查什么
| 检查项 | 发现什么 |
|---|---|
| 公开的 source map | 你最大的几个脚本旁边的 .map 文件(通过响应头、注释或直接请求发现),以及它是否内嵌了原始源码。含源码的 map 会把分数上限压到 10,只含映射的 map 上限为 50。公开的 .git 目录等同于含源码的 map。 |
| 可读代码 | 对你自己的每个脚本,衡量读者能以普通代码形式还原多少:英文字符串、有意义的名称和属性访问,基于词法单元测量。每个文件被评为原样、压缩或混淆。占 75 分,按字节加权。逐个 token 的版本参见Protection Map。 |
| 泄露的凭据 | 私钥、云服务密钥、支付密钥、代码仓库和聊天令牌、数据库 URL 和 bearer token,打码后连同上下文显示。占 25 分。邮箱、IP 地址和可公开的浏览器密钥只列出,不计分。 |
| 第三方代码 | 从网站提供的第三方 SDK,通过主机、路径或许可证注释识别。单独列出,不计入分数。 |
| 代码卫生 | eval()、Function 构造函数、document.write 和原始 HTML 注入点、第三方域名以及检测到的技术栈。只列出,不计分。 |
暴露的 source map
source map 会把已发布的代码包链接回你原始的、可读的源码。切勿把它发布到生产环境:攻击者下载它,就能像读你写的代码一样读出来。
audit 会抓出它。使用 AfterPack 的生产环境构建不会写出 .map,还会删除打包工具写出的 map(参见 sourceMap.enabled 和 sourceMap.emitUrl),但部署时从别处复制进来的 map 仍然会被发布出去。
解读结果
CLI 会在每个阶段完成时打印结果,critical 和 high 级别的发现会在出现时随即显示,最后以一个汇总框收尾:百分制得分、脚本数量、按严重程度分类的发现,以及检测到的技术栈。结尾会列出每一条严重发现,并附一个完整报告的网页链接。
从上到下阅读:
- 先看 source map。 公开的 map 会把你写的源码原样交给读者,不管构建做了什么。从生产环境中移除所有
.map文件。 - 接着看凭据。 轮换任何泄露的凭据,然后停止发布它。
- 最后看可读代码。 如果你自己的文件被评为原样或压缩,那就没有实质性的保护。用 AfterPack 跑一次构建(快速上手大约五分钟)。
默认输出的是人类可读的文本;使用 --diagnostics.format=json 时,stdout 上只会输出一份 JSON 文档,其中包含发现、得分和报告链接,所有人类可读的内容都会转移到 stderr;再加上 --diagnostics.level=none 则会同时关闭进度阶段的输出。可分享的报告始终是这次运行结束时给出的那个网页链接。
未评级
页面没有网站自有代码,或扫描器无法读取这些代码时,扫描不会给分。报告显示 未评级 而不是一个数字,并说明原因:
- 没有自有 JavaScript。 页面没有加载任何来自网站本身的脚本,因此没有可评级的内容。请扫描一个加载应用的页面,例如产品页面。
- 被拦截。 网站用机器人验证或错误页面回应了扫描器,而不是页面本身。
- 脚本未能读取。 页面加载了自有脚本,但扫描器无法读取其中的大部分。请重新扫描。
被拦截的扫描,或脚本未能读取的扫描,不会在 30 分钟的重复扫描窗口内被复用,因此新的扫描会立即运行。只有少数脚本无法读取时,扫描会按已读取的脚本评级,报告会注明漏掉了多少个。
退出码
| 退出码 | 触发条件 |
|---|---|
0 | 扫描已完成。即使发现了严重问题也是如此。 |
1 | 扫描失败:URL 不可达、服务端错误、触发了每日速率限制,或者流在完成前中断。 |
64 | 误用:没有给出 URL、给了不止一个 URL,或者 URL 格式不正确。 |
这些是 audit 自己的退出码。混淆运行使用的构建退出码是另外一套。
因为完成的扫描无论发现了什么都会以 0 退出,npx afterpack@latest audit … && deploy 不会因为发现问题而失败。没有严重程度阈值参数:如果你想据此做门禁判断,请自己从 --diagnostics.format=json 中读取发现结果。把 audit 当作一个由你手动阅读的发布前审查步骤来用。会让构建失败的环节是混淆运行本身。
未认证的扫描每个 IP 每 24 小时限 3 次,同一个网站每小时最多扫描 10 次。达到限制时会打印还需等待多久,并以 1 退出。30 分钟内重复扫描同一个 URL 会返回现有报告,不计入次数。
AfterPack 徽章
把徽章放在网站页脚或 README 中。当你的主机的最新扫描发现网站自身代码是 AfterPack 输出、没有公开的 source map 或凭据、且评级为 A 时,它显示 Protected by AfterPack;否则显示最新分数;你的主机还没有任何扫描为网站评级时显示 not graded。从未扫描过的主机显示 Scan with AfterPack。徽章链接到最新报告,并在新扫描后一小时内更新。
页脚:
<a href="https://www.afterpack.dev/security-scanner/site/yoursite.com?ref=badge" rel="noopener" title="AfterPack security scan">
<img src="https://www.afterpack.dev/badge/yoursite.com.svg?style=compact&theme=dark" alt="AfterPack badge" width="200" height="32" loading="lazy">
</a>README:
[](https://www.afterpack.dev/security-scanner/site/yoursite.com?ref=badge)样式:页脚用 compact(200×32)和 wide(236×48),README 用 flat(20 px)。主题:dark 和 light。安全扫描器的每个结果页都有该主机的这些代码片段。
下一步
- 构建与 CI:把混淆嵌入你的发布流水线,并固定一个 seed 以获得可复现的输出。
- 最佳实践:该标记什么、该保留什么不动,以及 source map 的规则。
- 安全扫描器:在浏览器里做同样的检查,无需安装,附完整的可分享报告。
- Protection Map:一旦你开始混淆,可以查看你自己构建的逐 token 视图。
- AfterPack 不能替代什么:泄露的密钥需要轮换;事后混淆它没有用。