AI生成代码的隐患:神对手还是猪队友

自从ChatGPT问世,其创造能力让世人震惊,甚至其能力也让设计和开发它的人感到不可思议。当大家娱乐的劲头散去,自然而然会想到利用大语言模型来解决专业的问题,其中一项就是写代码,于是ChatGPT问世不久微软就推出了Copilot,毕竟这家公司不仅给OpenAI投资了130亿美金,旗下还拥有GitHub这样规模最庞大的代码托管平台,2023年,Cursor问世,这款代码编辑器相当于是一款AI版的VS Code,可以替代VS Code进行编程,不同之处在于只需要用输入指令告诉编辑器要写什么用的代码即可,简直成了开发者的“外挂神器”。

代码生成技术的背后靠的是海量的代码数据训练,它可以根据开发人员的已经输入的代码猜测意图并自动生成后续的代码,也可以直接用自然语言描述程序的预期来生成代码,比如“请用快速排序算法写一段程序排列用户输入的任意正整数”,它几秒钟就可以生成出来。这些工具能让开发效率起飞,尤其是对付那些机械化、重复性的活儿,甚至让能够不懂编程的人也可以很容易、很快制作他们想要的结果,笔者的一个朋友使用Claude(当前最牛逼的代码生成大模型应用,没有之一)制作了一个旅行网站,她对结果很是喜欢。程序员是不是很快要失业?快速生成代码是不是真的让全民编程时代到来?

从大模型的原理可以发现,AI辅助生成代码的本质就是一个基于海量公开代码库的统计模型,它能模仿人类写代码的套路,但压根儿不理解代码背后的逻辑,更别提什么安全性了。换句话说,它就是个“高智商的复读机”,能快速吐出代码,但压根儿不会思考“这代码放这儿合不合适”或者“会不会被人黑”。举个例子,你让它写个文件读取函数,它可能给你弄个不检查路径的版本,结果攻击者随便输个../../etc/passwd,你的服务器就裸奔了,或者说是管杀不管埋。 

埋雷大师:AI生成代码的安全隐患

首先,AI 有个“抄袭”的天赋,特别擅长复制已知漏洞,它是靠公开代码库训练的,GitHub上星标几万的项目看着很厉害,可客观上里面藏了多少漏洞无人知晓。SQL注入、缓冲区溢出、不安全的反序列化,这些老掉牙的漏洞在代码库里多得跟地里的野草似的,甚至有的人直接用正则搜索通过GitHub刷CVE漏洞(实际很多漏洞都非常简单),但预训练时候的模型是不关注代码安全的,它照着“课本”抄就是了。

比如,它可能随手给你生成一段这样的SQL语句:

1
"SELECT * FROM users WHERE username = '" + userInput + "'"

这是入门级的 SQL 注入漏洞,攻击者也可以很轻易构造一个恶意输入’; DROP TABLE users; –,这可以删掉users的数据表。代码生成时候,模型是不会管什么叫安全的,它只有一条逻辑:“这代码在训练集里见过,挺常见的,给你用吧!”它就像个手速极快的GitHub代码搜索专家,把那些已知的、公开的安全隐患一股脑儿塞到自动生成的代码里。

其次是业务逻辑的问题。无论是哪种大模型,它们压根儿不懂业务需求,业务需求全靠用户在Prompt中的输入,也就是说用户就是产品经理,也不会根据经验自动补齐功能安全或安全功能策略。比如让它写个登录验证代码,它可能会生成不校验输入、不处理用户口令的半成品,像下面这样:

1
2
3
function login(username, password) {
return db.query("SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'");
}

这代码完全没考虑输入过滤,更别提密码明文存储问题,连个基本的用户口令哈希都不加,攻击者拖库就能拿走所有用户数据。在代码生成过程中,模型是不会主动问“这业务需要权限控制吗?”(现在的Deep Research模式下可能会)它只会机械地生成代码,像个没脑子的机器人。业务逻辑的复杂性和安全性,既需要产品经理设计,也需要开发者在设计中把关。

还有,AI生成的代码有时候表面上完美无缺,但实际暗藏风险,比如,它可能给你个哈希函数,看着挺高大上,结果用的是MD5这种早就不被建议的弱强度算法,或者直接把密钥硬编码在代码里,像这样:

1
2
3
def pass_hash(password):
hash_object = hashlib.md5(password.encode())
return hash_object.hexdigest()

这种“看着对,其实错”的生成结果很容易让那些没安全技能和安全经验的开发人员或者行外人员误解它的运行效果。你以为它帮你解决了问题,殊不知它在你代码里埋了个雷,等着上线后炸给你看。

更别提依赖性问题了。AI生成的代码有时候会自作聪明引入一堆乱七八糟的依赖,有些还是过时得不能再过时的老版本库,比如,它可能随手用了个10年前的HTTP库,里面的CVE(通用漏洞披露)编号多得能写本书。你用了这些依赖,等于给攻击者开了后门,服务器还没跑热就被打穿了。这种“自作主张”的行为,会让开发者在不知不觉中背上安全风险的黑锅。

最后,AI生成的代码基本上是没测试的半成品。它生成的玩意儿可能在边界条件下直接崩溃,或者压根儿跑不通,笔者就遇到过几次,其代码性能和代码效率需要人工进行修订和完善。比如,你让它写个文件上传功能,它可能忘了检查文件大小,结果用户传个10GB的文件就发现由于连接超时无法完成上传操作。你以为它帮你省了写代码的时间,其实是给自己留了个定时炸弹,所以AI生成的代码往往需要有经验的开发者再做调试和完善,稍不留神,反而可能增加工作量。

程序员的保命建议

首先,代码审查是重中之重。AI生成的代码,别直接复制粘贴就运行,每一行都得看清楚。至少可以先用静态分析工具扫一遍,看看有没有漏洞。审查代码是开发者的基本功,AI只是辅助工具,不是免死金牌。

安全开发能力是体现开发人员水平的基本。AI再聪明也不会替你学习安全漏洞和安全开发能力。对于各类基本的安全漏洞的防御开发和修复开发得扎扎实实掌握,笔者曾经写一个文件上传功能的代码,实际是威胁建模+安全开发同时在做,虽然比快速写一个能用的功能要耗费更多时间,但也更考验开发能力和安全能力。安全意识和技能是开发者安身立命的本钱,AI只能锦上添花,救不了命。

还有,安全编码规范得老老实实看一看。多采用行业最佳安全实践,别自作聪明,尤其是数据加密解密相关的代码。行业最佳实践是全世界的开发人员和安全人员持续积累的结果,比AI的生成靠谱多了。安全编码指南是无数实战检验出来的硬道理,开发者要是懒得遵守,早晚会在工作结果上吃亏。

代码的同行评审也不能省。AI写的代码,哪怕看着再漂亮,也得让队友过一遍眼。顺便还能让团队里那些AI信徒保持清醒,别老觉得AI是万能的(要不然自己的价值在哪里)。团队协作和互相审查是提升代码质量的关键,AI再牛也代替不了人的判断,当然还是要开发人员老老实实学习、理解和掌握计算机和软件的内功,比如《编程珠玑》、《深入理解计算机系统》、《UNIX编程艺术》、《TCP/IP协议详解》《Effective编程系列》等等,越是深入代码性能,越会有兴趣深入底层实现,正如史蒂夫.乔布斯非常认同的一句格言:

“对待软件严肃认真的人,应该制造自己专属的硬件”

(People who are serious about software should make their own hardware)。

AI生成代码是神助手还是猪队友

AI辅助生成代码这事儿是甜头和苦果并存。甜头是显而易见的,效率高了,那些写CRUD写到吐血的日子可以少点(尤其是重复的、简单的代码生成),开发者能喘口气、喝杯咖啡了。苦果也不少,安全隐患多了,代码质量参差不齐,一个不小心就被它的结果坑到喷出喝下的咖啡。

有的人以为自己从此也可以写代码,或者觉得写代码让自己也能成为独立开发者,实际上,AI生成的代码就像路边摊的炸鸡,闻着香,吃下去指不定拉肚子。AI是把双刃剑,用得好是帮手,用不好就是“猪队友”,它花里胡哨的外表确实能唬人,但深入到以上问题还是得靠人的大脑,至少目前它顶多是个干活儿的工具,成不了安全开发的救世主。更有意思的是,最近有人爆出Cursor的一个有趣的Bug (https://forum.cursor.com/t/cursor-told-me-i-should-learn-coding-instead-of-asking-it-to-generate-it-limit-of-800-locs/61132 ),Cursor在响应中撂挑子不干了:我不能为你生成代码,这完全是你自己的工作……你应该自己搞定代码逻辑,好让你自己能理解和维护系统。


AI生成代码的隐患:神对手还是猪队友
https://insbug.net/ai-generated-code-pitfalls-ally-or-foe/
作者
裴伟伟
发布于
2025年3月15日
许可协议