执行 AI 推荐脚本前,先核验文件
通过修改安装脚本前后的校验实验,展示 SHA-256 检查与退出码如何阻止执行被改动的文件。强调校验值必须来自可信渠道,匹配结果本身不能证明脚本安全。
AI 深度解读
AI 给出一条 curl … | sh,安装过程确实省事,但脚本还没看过,就已经交给 Shell 执行了。作者用一次很小的实验说明:先保存脚本,再校验 SHA-256,可以拦住文件内容发生变化的情况。
但校验通过不等于脚本安全。对程序员更有用的,是弄清校验值该从哪里取、退出码怎么参与执行控制,以及哪些风险仍然需要签名验证和人工检查。
先下载再校验,究竟能拦住什么
作者记录了安装脚本的 SHA-256 校验值,然后向文件追加一行内容。再次检查时,sha256sum -c 输出 install.sh: FAILED,并提示 WARNING: 1 computed checksum did NOT match,退出码为 1。未修改的文件则输出 OK,退出码为 0。
两次实验都没有执行脚本。它验证的是文件变化能否被发现,没有验证安装脚本是否可信。
SHA-256 会根据文件内容计算出一个摘要。拿下载文件的摘要与预期值比较,可以判断两者是否一致。GNU coreutils 手册将这类工具归入 SHA-2 哈希工具;它们负责计算和比较摘要,不负责理解脚本会做什么。
作者给出的操作顺序是先保存、再校验、最后阅读:
curl -fsSLo install.sh https://example.com/install.sh # 先保存为文件,不要通过管道交给 Shell
echo "<sha256-from-the-project's-release-page> install.sh" | sha256sum -c - # 退出码 0 表示匹配
less install.sh # 执行前先阅读
要注意第二行:占位符必须替换成项目发布页提供的真实 SHA-256,不能照抄执行。第一行也只是示例地址,并不是某个项目的安装入口。
校验通过,为什么仍然不能直接放心执行
校验通过只证明文件与所比较的校验值一致。
这里有两个不同的问题:文件有没有变化,以及文件最初是否值得信任。SHA-256 比较处理的是前一个问题。
如果攻击者同时控制脚本和校验值,就能让恶意脚本顺利通过检查。从 AI 回答里复制一个校验值,也不能把它当作可信依据。作者建议从项目自己的 release 页面或带签名的发布说明取值;项目提供签名验证时,优先使用。
但原文没有展开签名验证步骤,也没有说明如何确认签名密钥的可信来源。这一部分仍需要按项目提供的流程处理。
退出码则让校验能够参与自动化。按原文引用的 coreutils 9.7 帮助信息,-c、--check 用于读取校验值并检查文件;--status 不输出检查结果,只通过状态码表示成功与否。
下面这条命令解决的是「校验失败后仍继续执行」的问题:
sha256sum -c file.sha256 && bash install.sh
要注意 &&:只有前面的检查成功,后面的 bash install.sh 才会运行。不过,它没有包含前面示例里的人工阅读步骤。需要审阅脚本时,应当在校验后停下来查看,审阅完成再执行。
我的判断
作者的建议成立,而且适合写进 AI 编程助手的规则:安装命令不要直接把下载内容交给 Shell,先把文件留在本地,让校验和阅读都有机会发生。
这个实验的边界也很清楚。它展示了追加一行内容后校验失败,没有给出更广泛的攻击测试或对照数据。因此,它能支持「检查内容一致性」这个结论,不能支持「通过校验就安全」。
与直接使用 curl … | sh 相比,保存文件增加了检查机会;与项目提供的签名验证相比,单独比较哈希仍然依赖校验值来源。即使来自官方发布页,校验值也不能证明脚本没有危险操作。
less install.sh 同样不是安全认证。作者没有给出脚本审阅方法,阅读者能否识别风险仍是前提。如果脚本还会继续下载其他内容,对当前文件的校验也不能覆盖那些后续内容。
能拿来做什么
- 给日常 AI 编程助手补一条明确规则:「不要建议
curl … | sh;先保存文件,从官方 release 页面获取校验值,校验后展示脚本。」 - 安装前端或 Node 开发工具时,遇到 AI 提供的远程安装脚本,先要求它给出下载、校验、阅读三个独立步骤,校验值自行从项目发布来源获取。
- 编写安装自动化时,用校验命令的退出码控制后续步骤;需要人工审阅的脚本,在审阅完成后再执行。
- 项目提供签名验证时,按项目说明验证签名;如果没有找到可信的校验值来源,就明确保留这个缺口,不让 AI 补出一个看似完整的值。