你让AI写个用户注册功能,它反手给你塞了段MD5哈希代码。不是SHA-256,不是bcrypt,是1992年诞生、2004年就被证明不安全的MD5。更诡异的是,这事我三周内撞见三次——不同开发者,不同项目,同一串危险代码

正方:AI只是照本宣科

打开网易新闻 查看精彩图片

Cursor没发疯。它的行为完全符合训练数据的统计规律。

当你输入"implement user registration",模型做的不是"思考什么是最佳实践",而是模式匹配。它在数十亿token里找"password hash Node.js"最常见的共现组合,然后吐出答案。

问题在于数据来源的时间分布。2008到2019年间,StackOverflow答案、技术博客、GitHub片段里充斥着这样的代码:

「const hash = crypto.createHash('md5').update(password).digest('hex');」

这段模式出现了数百万次。bcrypt虽然2012年后就是正确答案,但存量内容被旧数据淹没。模型学到的"典型"解决方案,恰恰是过时的解决方案。

这不是模型架构缺陷,是训练语料的时间偏见。AI没有安全意识,只有频率意识。

反方:开发者不能甩锅给工具

但把责任全推给AI,等于承认开发者是代码的搬运工而非思考者。

原文作者提到,那位Node.js开发者"不是粗心"——但MD5用于密码存储是安全领域的常识性错误。CWE-328(使用损坏或有风险的加密哈希函数)在漏洞数据库里躺了十几年,任何生产环境代码审查都该拦截这类代码。

更隐蔽的风险在于:SHA-256看起来比MD5"现代",但同样错误。

SHA-256的设计目标是速度——每秒能在GPU上处理数十亿次哈希。这对文件完整性校验是优点,对密码存储是致命缺陷。攻击者用消费级显卡配合字典,破解SHA-256哈希的速度比MD5更快。

AI生成代码通过了"能跑"的测试,但没通过"该用吗"的审查。这个判断缺口,最终是人的责任。

技术拆解:为什么速度是敌人

密码哈希的核心矛盾在于:合法用户登录时需要快,攻击者暴力破解时需要慢。

MD5、SHA-1、SHA-256都是通用哈希函数,设计目标是高效计算。bcrypt和Argon2id则是有意"做慢"的算法——通过可配置的计算成本,让单次哈希耗时200-300毫秒。

对用户来说,登录多等0.3秒无感知。对攻击者来说,每秒尝试次数从数十亿骤降到个位数,字典攻击的经济成本变得不可承受。

原文给出的正确实现:

「const bcrypt = require('bcrypt');

const hash = await bcrypt.hash(password, 12);」

12轮是2012年后的推荐下限。OWASP目前的首选是Argon2id,内存硬型设计能抵抗GPU/ASIC专用硬件攻击:

「const argon2 = require('argon2');

const hash = await argon2.hash(password);」

Python同理:

「import bcrypt

hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))」

我的判断:这是AI辅助编程的结构性痛点

这件事的重要性不在于"AI会写烂代码"——人类写的烂代码更多。关键在于AI输出的"平均质量"陷阱。

Cursor生成的是训练数据里的最常见解,而非当前最佳实践。在技术领域,这两者往往存在时间差:旧方案传播更广,新方案更安全。当AI成为主要编码工具,这种滞后会被批量复制到无数新项目。

更麻烦的是反馈循环。如果今天的AI生成MD5代码被大量采纳,明天的训练数据里MD5出现频率更高,模型更难摆脱这个模式。

短期应对很朴素:关键安全代码必须人工复核,不能把AI输出直接塞进生产环境。长期则需要训练数据的时间加权策略——让2019年后的安全实践获得更高采样权重,或者显式注入"当前推荐"的知识层。

否则我们会持续收到2026年的MD5密码库,像某种技术考古的黑色幽默。