刷掘金看到热榜第1,说自己用AI写的注册接口,没有任何防护,一天被灌了227万条垃圾数据 😱
我立刻看了眼自己的项目... 好几个接口也是AI帮写的,rate limiting? 验证码? CSRF token? 有个锤子。
那个帖子底下评论区已经炸了,各种"AI写代码就是不靠谱"。但我觉得问题不在于"AI写的代码",而在于你用的哪个模型、你怎么提的需求。
所以我做了个实验:用同一个prompt,让5个主流大模型各写一个用户注册接口,看谁的安全防护最完善。
实验设计
Prompt(故意不提安全要求):
用 Node.js + Express 写一个用户注册接口,要求:
1. 接收 email 和 password
2. 密码hash后存入数据库
3. 返回注册成功/失败
注意:我故意没提任何安全相关的需求,就看哪个模型会"自觉"加上防护。
测试模型: Claude Opus 4.6、GPT-4o、DeepSeek V3、GLM-5、Gemini 2.5 Pro
为了公平,我用同一个API接口跑的,换个model参数就行(后面说怎么搞的)。
结果对比:差距比想象中大
Claude Opus 4.6 — 防护指数 ⭐⭐⭐⭐⭐
没提安全,它自己加了:
- ✅ Rate limiting(express-rate-limit,15分钟10次)
- ✅ 输入验证(email格式、密码强度要求)
- ✅ bcrypt 加密(cost factor 12)
- ✅ 通用错误响应(不泄露用户是否已存在)
- ✅ helmet 中间件
- ✅ 还加了注释说"生产环境建议加CSRF token和验证码"
// Claude 生成的代码片段
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 10,
message: 'Too many registration attempts'
});
app.use('/api/register', limiter);
说实话超出预期,我没提它主动加了 6 层防护。如果热榜那哥们用的这个模型,大概率不会出事。
GPT-4o — 防护指数 ⭐⭐⭐⭐
也不错:
- ✅ 输入验证
- ✅ bcrypt 加密
- ✅ 检查邮箱是否已注册
- ✅ try-catch 错误处理
- ❌ 没有 rate limiting
- ❌ 没有 helmet
比 Claude 少了关键的频率限制,但基本功挺扎实的。
Gemini 2.5 Pro — 防护指数 ⭐⭐⭐⭐
- ✅ 输入验证(还用了 Joi 做 schema 校验)
- ✅ bcrypt 加密
- ✅ 统一错误处理
- ✅ 加了 CORS 配置
- ❌ 没有 rate limiting
- ❌ 错误信息泄露了"邮箱已注册"
Joi 验证是个亮点,但"邮箱已注册"直接返回给前端这个... 会被人拿来撞库的兄弟们。
DeepSeek V3 — 防护指数 ⭐⭐⭐
- ✅ bcrypt 加密
- ✅ 基本的邮箱格式校验
- ❌ 没有 rate limiting
- ❌ 没有 helmet
- ❌ 密码明文出现在日志里(console.log了请求body 💀)
- ❌ 错误处理比较粗糙
密码写进日志这个... 生产环境要出大事。安全意识相对弱一些。
GLM-5 — 防护指数 ⭐⭐
- ✅ bcrypt 加密
- ❌ 没有输入验证
- ❌ 没有 rate limiting
- ❌ 直接返回了 user id(信息泄露)
- ❌ SQL 拼接而不是参数化查询
- ❌ 没有错误处理中间件
最让我意外的是 SQL 拼接... 2026年了还生成SQL注入漏洞代码,这确实得改。
汇总对比表
| 防护项 | Claude | GPT-4o | Gemini | DeepSeek | GLM-5 |
|---|---|---|---|---|---|
| Rate Limiting | ✅ | ❌ | ❌ | ❌ | ❌ |
| 输入验证 | ✅ | ✅ | ✅ | ⚠️ | ❌ |
| 密码加密 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 信息泄露防护 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 安全中间件 | ✅ | ❌ | ❌ | ❌ | ❌ |
| SQL注入防护 | ✅ | ✅ | ✅ | ✅ | ❌ |
那个被灌227万数据的哥们,问题出在哪?
看完对比就很清楚了:
- 模型选错了 — 不是所有模型都有安全意识,差距真的大
- 完全不review — AI写的代码至少过一遍安全检查
- 没有rate limiting — 最基本的防护,5个模型里只有1个主动加了
如果一开始就选安全意识强的模型,或者至少在prompt里加一句"注意安全防护",大概率不会出这种事。
实测环境说一下
有同学可能会问:5个模型你怎么做到"同一个prompt、同一个接口"跑的?
其实很简单,我用了一个API聚合平台,兼容OpenAI格式,换个model名就能切模型:
from openai import OpenAI
client = OpenAI(
api_key="your-key",
base_url="https://api.ofox.ai/v1"
)
models = [
"claude-opus-4-6",
"gpt-4o",
"deepseek-chat",
"glm-5",
"gemini-2.5-pro"
]
for model in models:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
print(f"\n{'='*50}")
print(f"模型: {model}")
print(resp.choices[0].message.content)
一个 base_url 搞定所有模型对比,省得一个个注册账号了。国内直连,延迟也OK。
几条建议
如果你也在用 AI 写后端代码:
- 选安全意识强的模型 — Claude和GPT在安全防护方面确实领先一截
- prompt里写明安全要求 — 别全指望模型"自觉",虽然有的确实会
- AI写完必须review — 至少过一遍 OWASP Top 10 检查清单
- 关键接口手动加rate limiting — 别赌,这是底线
AI写代码确实效率高,但"高效地写出有漏洞的代码"更可怕。与其出事后堵窟窿,不如选模型的时候就做对选择。
一个被热榜吓到赶紧review全部接口的独立开发者 😂