AI编程的安全陷阱:10个常见的安全漏洞及防范方法
2026年,AI编程工具越来越强大,但AI生成的代码并不安全。
我审查了100+个AI生成的代码项目,发现了10个常见的安全漏洞。
这篇文章不是"恐吓文",而是实战指南——我会分享真实案例、漏洞原理、防范方法、工具推荐,帮你写出更安全的代码。
写在前面:为什么AI生成的代码不安全?
2026年,很多开发者用AI生成代码,但不知道AI生成的代码有安全漏洞。
原因:
- AI训练数据的局限性:AI是在公开代码上训练的,而公开代码里也有很多安全漏洞
- AI不理解安全上下文:AI只知道"怎么实现功能",不知道"怎么实现安全的功能"
- 开发者过度信任AI:很多开发者盲目接受AI生成的代码,不审查安全性
我的观点:
AI生成的代码能跑,但不一定安全。
你需要有能力审查AI生成的代码的安全性。
一、10个常见的安全漏洞及防范方法
漏洞1:SQL注入(SQL Injection)
漏洞描述
SQL注入是指攻击者通过在输入中插入恶意的SQL代码,从而操控数据库执行非预期的操作。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 直接拼接用户输入到SQL语句中(危险!)
const sql = `SELECT * FROM users WHERE username = '${username}' AND password = '${password}'`;
db.query(sql, (err, result) => {
if (result.length > 0) {
res.json({ success: true, user: result[0] });
} else {
res.json({ success: false, message: '登录失败' });
}
});
});
漏洞原理:
- 如果用户输入
username = admin' --,SQL语句变成:SELECT * FROM users WHERE username = 'admin' --' AND password = 'xxx' --是SQL注释符,后面的密码校验被注释掉了- 攻击者可以不用密码就登录admin账户
安全的代码(防范方法)
// ✅ 安全的代码(使用参数化查询)
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 使用参数化查询(防止SQL注入)
const sql = 'SELECT * FROM users WHERE username = ? AND password = ?';
db.query(sql, [username, password], (err, result) => {
if (result.length > 0) {
res.json({ success: true, user: result[0] });
} else {
res.json({ success: false, message: '登录失败' });
}
});
});
防范方法总结:
- 永远使用参数化查询(Prepared Statement)
- 不要拼接用户输入到SQL语句中
- 使用ORM框架(如Sequelize、TypeORM),它们内置了防SQL注入机制
漏洞2:跨站脚本攻击(XSS)
漏洞描述
**XSS(Cross-Site Scripting)**是指攻击者在网页中插入恶意的JavaScript代码,当其他用户访问该页面时,恶意代码会执行,从而窃取用户信息、篡改页面内容等。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
app.get('/search', (req, res) => {
const { q } = req.query;
// 直接把用户输入显示在页面上(危险!)
res.send(`
<html>
<body>
<h1>搜索结果:${q}</h1>
</body>
</html>
`);
});
漏洞原理:
- 如果用户输入
<script>alert('XSS')</script>,页面会弹出一个alert框 - 攻击者可以构造更恶意的代码,如窃取Cookie、发送恶意请求等
安全的代码(防范方法)
// ✅ 安全的代码(对用户输入进行转义)
import { escape } from 'lodash';
app.get('/search', (req, res) => {
const { q } = req.query;
// 对用户输入进行转义(防止XSS)
const safeQ = escape(q);
res.send(`
<html>
<body>
<h1>搜索结果:${safeQ}</h1>
</body>
</html>
`);
});
防范方法总结:
- 对用户输入进行转义(把
<转成<,把>转成>等) - 使用前端框架(如React、Vue),它们内置了XSS防护
- 设置Content-Security-Policy(CSP)响应头
漏洞3:硬编码密钥(Hardcoded Secrets)
漏洞描述
硬编码密钥是指把敏感信息(如API密钥、数据库密码、JWT密钥等)直接写在代码里。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
const jwt = require('jsonwebtoken');
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 硬编码JWT密钥(危险!)
const token = jwt.sign(
{ username },
'my-secret-key-12345', // ❌ 硬编码密钥
{ expiresIn: '1h' }
);
res.json({ token });
});
漏洞原理:
- 如果代码被上传到GitHub等公开平台,攻击者可以直接看到密钥
- 即使代码不公开,硬编码密钥也会被打包到前端代码中,攻击者可以反编译看到
安全的代码(防范方法)
// ✅ 安全的代码(使用环境变量)
const jwt = require('jsonwebtoken');
require('dotenv').config();
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 使用环境变量存储密钥
const token = jwt.sign(
{ username },
process.env.JWT_SECRET, // ✅ 从环境变量读取
{ expiresIn: '1h' }
);
res.json({ token });
});
防范方法总结:
- 永远不要把敏感信息写在代码里
- 使用环境变量(如
.env文件)存储敏感信息 - 把
.env文件加入.gitignore(避免被提交到代码仓库) - 使用密钥管理服务(如AWS Secrets Manager、Azure Key Vault)
漏洞4:不验证用户输入(Missing Input Validation)
漏洞描述
不验证用户输入是指相信用户的输入都是合法的,不做任何校验。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
app.post('/api/users', (req, res) => {
const { username, email, age } = req.body;
// 不做任何验证,直接插入数据库(危险!)
const sql = 'INSERT INTO users (username, email, age) VALUES (?, ?, ?)';
db.query(sql, [username, email, age], (err, result) => {
res.json({ success: true, id: result.insertId });
});
});
漏洞原理:
- 用户可以输入恶意数据(如超长字符串、非法字符、负数等)
- 可能导致数据库错误、应用崩溃、甚至安全漏洞
安全的代码(防范方法)
// ✅ 安全的代码(验证用户输入)
const Joi = require('joi');
app.post('/api/users', (req, res) => {
const { username, email, age } = req.body;
// 定义验证规则
const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(1).max(120).required()
});
// 验证用户输入
const { error, value } = schema.validate({ username, email, age });
if (error) {
return res.status(400).json({ error: error.message });
}
// 验证通过,插入数据库
const sql = 'INSERT INTO users (username, email, age) VALUES (?, ?, ?)';
db.query(sql, [value.username, value.email, value.age], (err, result) => {
res.json({ success: true, id: result.insertId });
});
});
防范方法总结:
- 永远验证用户输入(后端验证 + 前端验证)
- 使用验证库(如Joi、Yup、Zod)
- 验证规则要严格(类型、长度、格式、范围等)
漏洞5:不安全的直接对象引用(Insecure Direct Object Reference, IDOR)
漏洞描述
IDOR是指用户可以通过修改参数(如ID),访问到不属于自己的数据。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
app.get('/api/orders/:id', (req, res) => {
const { id } = req.params;
// 直接查询订单,不验证订单是否属于当前用户(危险!)
const sql = 'SELECT * FROM orders WHERE id = ?';
db.query(sql, [id], (err, result) => {
res.json(result[0]);
});
});
漏洞原理:
- 用户A可以访问
/api/orders/123 - 用户B也可以访问
/api/orders/123(如果123是用户A的订单) - 攻击者可以遍历所有订单ID,看到所有人的订单
安全的代码(防范方法)
// ✅ 安全的代码(验证数据归属)
app.get('/api/orders/:id', (req, res) => {
const { id } = req.params;
const userId = req.user.id; // 从JWT或session中获取当前用户ID
// 查询订单时,同时验证订单是否属于当前用户
const sql = 'SELECT * FROM orders WHERE id = ? AND user_id = ?';
db.query(sql, [id, userId], (err, result) => {
if (result.length === 0) {
return res.status(404).json({ error: '订单不存在或无权访问' });
}
res.json(result[0]);
});
});
防范方法总结:
- 验证数据归属(查询数据时,加上用户ID条件)
- 使用间接引用(如用UUID代替自增ID)
- 实施访问控制(ACL、RBAC等)
漏洞6:CSRF(跨站请求伪造)
漏洞描述
**CSRF(Cross-Site Request Forgery)**是指攻击者诱导用户在已登录的网站上执行非预期的操作。
漏洞原理
- 用户登录了
bank.com,浏览器保存了Cookie - 用户访问了攻击者的网站
evil.com evil.com有一个隐藏的表单,会自动提交到bank.com/api/transfer(转账接口)- 浏览器会自动带上
bank.com的Cookie,所以请求会通过认证 - 用户在不知情的情况下被转了账
安全的代码(防范方法)
// ✅ 安全的代码(使用CSRF Token)
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(csrf({ cookie: true }));
app.get('/api/form', (req, res) => {
// 生成CSRF Token,发送给前端
res.json({ csrfToken: req.csrfToken() });
});
app.post('/api/transfer', (req, res) => {
// 验证CSRF Token(中间件会自动验证)
// 如果Token不正确,请求会被拒绝
res.json({ success: true });
});
前端代码:
// 前端在提交表单时,要带上CSRF Token
fetch('/api/form')
.then(res => res.json())
.then(data => {
const csrfToken = data.csrfToken;
// 提交表单时,带上CSRF Token
fetch('/api/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'CSRF-Token': csrfToken
},
body: JSON.stringify({ amount: 100, to: 'user123' })
});
});
防范方法总结:
- 使用CSRF Token
- 验证Referer头(检查请求是否来自自己的网站)
- 使用SameSite Cookie(防止Cookie被第三方网站携带)
漏洞7:不安全的文件上传(Insecure File Upload)
漏洞描述
不安全的文件上传是指允许用户上传任意文件,可能导致恶意文件被执行、服务器被入侵。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
const express = require('express');
const app = express();
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
app.post('/api/upload', upload.single('file'), (req, res) => {
// 不上传文件类型(危险!)
res.json({ success: true, filename: req.file.filename });
});
漏洞原理:
- 用户可以上传恶意文件(如
shell.php) - 如果服务器配置不当,恶意文件可能被执
- 攻击者可以拿到服务器的控制权
安全的代码(防范方法)
// ✅ 安全的代码(验证文件类型、限制文件大小)
const express = require('express');
const app = express();
const multer = require('multer');
const path = require('path');
// 限制文件类型
const upload = multer({
dest: 'uploads/',
fileFilter: (req, file, cb) => {
const allowedTypes = ['.jpg', '.jpeg', '.png', '.pdf'];
const ext = path.extname(file.originalname).toLowerCase();
if (allowedTypes.includes(ext)) {
cb(null, true);
} else {
cb(new Error('不支持的文件类型'));
}
},
limits: {
fileSize: 5 * 1024 * 1024 // 限制5MB
}
});
app.post('/api/upload', upload.single('file'), (req, res) => {
res.json({ success: true, filename: req.file.filename });
});
防范方法总结:
- 验证文件类型(白名单机制)
- 限制文件大小
- 重命名上传的文件(防止恶意文件名)
- 把上传的文件存在非Web根目录(防止被直接访问)
漏洞8:依赖库漏洞(Vulnerable Dependencies)
漏洞描述
依赖库漏洞是指项目使用的第三方库有安全漏洞,攻击者可以利用这些漏洞攻击你的应用。
问题原因
很多开发者在 package.json 中写了这样的依赖:
{
"dependencies": {
"express": "^4.17.0",
"lodash": "^4.17.0"
}
}
^4.17.0 表示"安装4.17.0及以上版本,但不超过5.0.0"。
如果 lodash 的4.17.15版本有安全漏洞,而你的项目安装的是4.17.15,那么你的项目也有漏洞。
防范方法
工具1:npm audit
# 检查项目依赖是否有安全漏洞
npm audit
# 自动修复安全漏洞
npm audit fix
工具2:Snyk
# 安装Snyk
npm install -g snyk
# 检查项目依赖是否有安全漏洞
snyk test
# 监控项目(持续检查)
snyk monitor
工具3:GitHub Dependabot
在GitHub仓库中启用Dependabot,它会自动检查依赖漏洞,并发送PR修复。
防范方法总结:
- 定期更新依赖(
npm update) - 使用安全扫描工具(npm audit、Snyk、Dependabot)
- 锁定依赖版本(
package-lock.json或yarn.lock)
漏洞9:不安全的JWT处理(Insecure JWT Handling)
漏洞描述
不安全的JWT处理是指在JWT(JSON Web Token)的实现和使用中存在安全漏洞。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
const jwt = require('jsonwebtoken');
// 没有验证alg字段(危险!)
app.post('/api/verify-token', (req, res) => {
const { token } = req.body;
// 不验证alg字段,可能存在算法混淆攻击
jwt.verify(token, 'secret', (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Token无效' });
}
res.json({ valid: true, user: decoded });
});
});
漏洞原理:
- JWT的Header中有个
alg字段,表示签名算法 - 攻击者可以把
alg改成none(表示不使用签名) - 如果服务端不验证
alg字段,就会接受这个伪造的Token
安全的代码(防范方法)
// ✅ 安全的代码(明确指定允许的算法)
const jwt = require('jsonwebtoken');
app.post('/api/verify-token', (req, res) => {
const { token } = req.body;
// 明确指定允许的算法(防止算法混淆攻击)
jwt.verify(token, process.env.JWT_SECRET, { algorithms: ['HS256'] }, (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Token无效' });
}
res.json({ valid: true, user: decoded });
});
});
防范方法总结:
- 明确指定允许的算法(
algorithms参数) - 使用强密钥(JWT密钥要足够复杂)
- 验证Token过期时间(
exp字段) - 不要把敏感信息放在JWT中(JWT是Base64编码,可以被解码)
漏洞10:日志中记录敏感信息(Sensitive Data in Logs)
漏洞描述
日志中记录敏感信息是指在日志中记录了密码、Token、信用卡号等敏感信息。
AI生成的"有漏洞的代码"
// ❌ 不安全的代码(AI可能生成这样的代码)
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 在日志中记录密码(危险!)
console.log(`用户尝试登录:username=${username}, password=${password}`);
// 验证逻辑...
});
漏洞原理:
- 日志文件可能被泄露(如被攻击者访问、被内部人员查看)
- 如果日志中记录了密码,攻击者可以直接拿到
安全的代码(防范方法)
// ✅ 安全的代码(不在日志中记录敏感信息)
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 不在日志中记录密码
console.log(`用户尝试登录:username=${username}`);
// 验证逻辑...
});
防范方法总结:
- 永远不要在日志中记录敏感信息(密码、Token、信用卡号等)
- 使用日志脱敏工具(如morgan、winston的脱敏插件)
- 限制日志访问权限(只有授权人员才能查看日志)
二、如何审查AI生成的代码的安全性?
方法1:手动审查(Code Review)
步骤:
- 对照上面的10个安全漏洞,逐一检查AI生成的代码
- 重点关注:输入验证、输出转义、密钥管理、访问控制
优点:准确率高
缺点:费时间
方法2:使用自动化工具
工具1:ESLint安全规则
# 安装ESLint安全规则插件
npm install eslint-plugin-security --save-dev
# .eslintrc.json 配置
{
"plugins": ["security"],
"rules": {
"security/detect-object-injection": "error",
"security/detect-secrets": "error",
"security/detect-unsafe-regex": "error"
}
}
工具2:Snyk代码扫描
# 安装Snyk
npm install -g snyk
# 扫描代码安全漏洞
snyk code test
工具3:GitHub Advanced Security
在GitHub仓库中启用Advanced Security,它会自动扫描代码安全漏洞。
优点:效率高
缺点:可能有漏报
方法3:让AI帮你审查代码
Prompt模板:
请审查以下代码的安全性,重点关注:
1. SQL注入
2. XSS
3. 硬编码密钥
4. 输入验证
5. 访问控制
6. CSRF
7. 文件上传
8. JWT处理
9. 依赖库漏洞
10. 日志敏感信息
请给出具体的改进建议。
代码:
[粘贴你的代码]
优点:快速、方便
缺点:可能不如人工审查准确
三、给开发者的安全编码建议
建议1:永远不要相信用户输入
核心原则:
所有用户输入都是不可信的。
前端验证 + 后端验证(前端验证是为了用户体验,后端验证是为了安全)
建议2:使用成熟的安全库
不要自己实现安全功能,使用成熟的安全库:
- 密码哈希:bcrypt、argon2
- JWT:jsonwebtoken(但要正确配置)
- 输入验证:Joi、Yup、Zod
- CSRF防护:csurf
- 安全头:helmet
建议3:定期学习安全知识
安全漏洞在不断演化,需要持续学习:
- OWASP Top 10(最常见的10个安全漏洞)
- 安全编码规范(如CERT、OWASP ASVS)
- 安全工具使用(如Snyk、npm audit)
四、总结:AI生成的代码需要人工审查安全性
写到这里,我来总结一下:
AI编程的安全陷阱核心问题:
- AI不理解安全上下文(只知道实现功能,不知道安全)
- AI训练数据包含漏洞代码(公开代码里也有很多安全漏洞)
- 开发者过度信任AI(盲目接受AI生成的代码)
如何防范:
- 手动审查代码(对照10个安全漏洞检查)
- 使用自动化工具(ESLint、Snyk、GitHub Advanced Security)
- 让AI帮你审查(但人工要再次确认)
- 持续学习安全知识(OWASP Top 10、安全编码规范)
给开发者的建议:
AI生成的代码能跑,但不一定安全。
你需要有能力审查AI生成的代码的安全性。

795

被折叠的 条评论
为什么被折叠?



