几乎每次入职通话我都会收到某种版本的这个问题,通常措辞很谨慎,好像提问的人一半期望被劝说不用担心。他们不该被劝说不用担心。安全是少数几个适度偏执才是正确校准的领域之一,无论代码是人写的还是模型写的。下面是我实际收到的问题,尽我所能直接回答。
AI 编写的代码是否比人写的代码更不安全?
平均而言,如果不加检查,是的——略微如此。几年前斯坦福的一项研究(Perry 等人,常被引用为对此问题的首次真正审视)发现,使用 AI 编码助手的开发者写出的代码安全性不如对照组——而更值得担心的是——他们对自己代码安全性的评价却高于实际水平。信心上升了,质量却下降了。Veracode 最近的 GenAI 代码安全扫描也给出了一个大致的数字:他们测试的 AI 生成代码样本中,大约每 10 个就有 4 个引入了至少一个可被利用的缺陷,通常是一些常见问题,比如缺少输入检查或较弱的默认设置。这并不意味着 AI 编写的代码注定不安全。这意味着未经审查的 AI 编写代码,风险与未经审查的人工编写代码相同,而“未经审查”正是危险真正存在的地方。一个写得快却从不被检查的模型,会犯下和周五下午赶工的初级开发者一样的错误——只是更快、更多。
我的 API 密钥和其他密钥会怎么样?
这是我真正会为之失眠的问题,因为这个错误在发生之前是隐形的。失败模式并不戏剧化——没有哪台服务器会像电影里的黑客场景那样被攻破。而是一个密钥被粘贴进对话框,又被回显进生成的文件,被提交,然后六个月后悄悄地以明文形式躺在某个仓库里,直到有人出于好奇对它跑了一次密钥扫描。在这个平台上,密钥永远不会存在于生成的源代码中——它们是在运行时从加密存储中注入的,限定在你的租户范围内,构建代理被指示只按名称引用它们,绝不按值引用。但如果你在别处构建,或者直接把凭证粘贴进任何工具的聊天窗口,那就应该假设这段文本现在已经成为某处训练相关日志的一部分,除非提供方明确声明并非如此。出于原则,在你完成测试的当天,轮换你曾经输入进聊天框的任何东西。
有人能通过提示词攻击我的网站,比如提示注入攻击吗?
这里混淆了两件不同的事情,而这个区别很重要。针对构建器的提示注入——有人诱骗正在构建你应用的 AI 去做你没有要求的事情——是一个真实的、已被研究过的风险,这也是为什么构建代理只运行受限范围的工具权限而不是无限制的 shell 访问,也是为什么任何涉及你文件系统或部署流程的操作都会经过一份可供事后审计的明确操作日志。针对你已上线应用的提示注入是另一个独立的问题,只有当你的应用本身在运行时嵌入了 LLM 时才适用——比如一个客服聊天机器人、一个 AI 搜索功能之类。如果确实如此,那就要把用户能输入的任何文本当作对该模型不可信的输入,就像你把它当作对 SQL 查询不可信的输入一样对待。这条规则很古老,新的地方只是换了哪个系统在解析这段字符串。
构建器在发布代码之前会自行检查漏洞吗?
自动化检测能可靠地捕获那些枯燥但高频出现的问题:硬编码的密钥、明显需要认证却缺失认证的接口、用字符串拼接而非参数构建的 SQL、带有已知 CVE 的依赖项。它们不擅长捕获的是业务逻辑缺陷——那种每一行代码单独看都没问题,而漏洞恰恰出在两个功能之间没人想到要一起检查的空隙里。比如一个可以无限叠加推荐奖金的折扣码。比如一个密码重置流程会泄露某个邮箱是否存在于系统中。这些需要有人理解这个应用是用来做什么的,而不仅仅是代码做了什么,而目前无论 AI 还是其他扫描工具,都还无法可靠地发现它们。自动化审查是一个底线,而不是上限。
它安装的第三方包呢?这算供应链风险吗?
是的,而且老实说,这比 AI 编写的代码本身在现实中的风险更大。大多数应用按代码行数计算,80% 到 95% 都是依赖项;构建器编写的代码只是覆盖在 npm、PyPI 或任何所用生态系统之上的一层薄薄的胶水代码。一个恶意或被劫持的包可以危及你的安全,无论围绕它的胶水代码是谁写的、用什么写的——参见 event-stream 和 colors.js 事件,看看这类问题在现实中是如何发生的。缓解措施枯燥但有效:锁定版本而不是跟踪最新版,优先选择有真实维护历史的包而不是上周才发布的包,并把依赖审计(`npm audit`、`pip-audit`,或任何适合你技术栈的工具)当作一个持续的习惯,而不是上线前的一次性步骤。
| 风险 | 由谁引入 | 通常如何被发现 | 由谁负责修复 |
|---|---|---|---|
| 生成代码中的硬编码密钥 | 构建过程,如果密钥注入不当 | 静态扫描,部署前检查 | 平台 |
| 缺失输入验证 | 模型或人,两者皆有可能 | 自动化加人工代码审查 | 两者皆是 |
| 存在漏洞的依赖项(CVE) | 上游包维护者 | 依赖审计 | 你,持续进行 |
| 业务逻辑缺陷(叠加漏洞、IDOR) | 把功能规范描述不完整的人 | 人工测试,通常只有在有人查看时才会发现 | 你 |
| 针对嵌入式 LLM 功能的提示注入 | 你已上线应用的最终用户 | 输入净化 + 受限模型权限 | 你 |
如果发生数据泄露,谁来承担责任?
从法律上讲——几乎总是——如果这是你的应用和你客户的数据,责任就在你身上。这一点让很多人感到意外,他们以为“是 AI 写的”能把责任转移到别处。但事实并非如此,这就好比雇了一个承包商并不能把建筑违规的责任从房产所有者身上转移走一样。平台对其掌控的基础设施负责:密钥如何存储、租户数据如何隔离、托管层本身是否打了补丁。但你所指定的应用逻辑、你选择收集的数据、你向用户提供的条款,都是你的责任。如果你在处理任何敏感信息——支付信息、健康信息,或受 GDPR、CCPA 约束的内容——请去阅读你所使用平台实际的数据处理协议,而不要假设“AI 构建”意味着多了一层法律保障。它并没有。
有位创始人曾半开玩笑地告诉我,她更信任 AI 写的代码,胜过自己写的,因为“它至少不会在凌晨两点犯困”。也许吧。但疲惫的人通常知道自己累了。而 AI 完全意识不到自己刚刚犯了错,它会用同样自信的语气告诉你代码已经完成——无论这段代码是完美无缺,还是漏洞百出。自信从来不是安全性的信号,无论它来自谁。
上线前应该花钱做一次真正的安全审计吗?
如果你在处理支付、存储任何监管机构会认定为个人身份信息(PII)的内容,或是在为将来会要求出示 SOC 2 报告的企业客户开发产品——那么答案是肯定的,不要让成本让你打退堂鼓。针对小型应用的定向审计费用从几百到几千美元不等,具体取决于范围,相比一封数据泄露通知信的代价,这已经很便宜了。如果你在做的是个人爱好项目、内部工具,或是没有真实用户数据风险的东西,付费审计就是过度投入了;改为使用免费和低成本的防护层——依赖项扫描、手动逐一检查每个身份验证边界(用户 A 能否通过修改 URL 看到用户 B 的东西?),以及请另一双人眼审查涉及资金或密码的部分。
人们最常犯的安全错误是什么?通常发生在什么时候?
往往不是在上线时——而是在上线三个月后,当应用运行正常、已经没人再关注它的时候。可能是一个未加防护的管理路由,因为它只被开发者本人以自己的身份登录测试过。可能是一个在生产环境中返回完整堆栈跟踪信息的调试接口。可能是数据库上一个“只是用来测试”、结果从未被更换的默认密码。这些都不是什么稀奇的漏洞。它们就相当于因为一时匆忙把备用钥匙藏在门垫下,然后就忘了这回事。解决办法不是更好的工具,而是一个五分钟的习惯:每个月抽五分钟,像攻击者一样审视你的应用,再像自豪的开发者一样看一遍。



