1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
| // 使用helmet设置安全HTTP头
const helmet = require('helmet');
app.use(helmet());
// 自定义安全头配置
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));
// 输入验证中间件
const { body, validationResult, check } = require('express-validator');
// 用户注册验证
const validateUserRegistration = [
check('username')
.isLength({ min: 3, max: 30 })
.withMessage('用户名长度必须在3-30个字符之间')
.matches(/^[a-zA-Z0-9_]+$/)
.withMessage('用户名只能包含字母、数字和下划线'),
check('email')
.isEmail()
.normalizeEmail()
.withMessage('请输入有效的邮箱地址'),
check('password')
.isLength({ min: 8 })
.withMessage('密码长度至少8个字符')
.matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/)
.withMessage('密码必须包含大小写字母、数字和特殊字符'),
check('age')
.isInt({ min: 18, max: 120 })
.withMessage('年龄必须在18-120之间'),
];
// 验证中间件处理
app.post('/api/users/register', validateUserRegistration, (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
errors: errors.array()
});
}
// 处理注册逻辑
const { username, email, password, age } = req.body;
// ...
});
// SQL注入防护
const mysql = require('mysql2/promise');
const getUserById = async (userId) => {
const connection = await mysql.createConnection(dbConfig);
try {
// ✅ 使用参数化查询
const [rows] = await connection.execute(
'SELECT * FROM users WHERE id = ?',
[userId]
);
return rows[0];
// ❌ 危险的字符串拼接
// const query = `SELECT * FROM users WHERE id = ${userId}`;
// const [rows] = await connection.execute(query);
} finally {
await connection.end();
}
};
// NoSQL注入防护
const mongoSanitize = require('express-mongo-sanitize');
app.use(mongoSanitize());
// 使用mongoose的验证和安全查询
const User = require('./models/User');
const findUsers = async (criteria) => {
// ✅ 使用mongoose的查询构建器
const query = {};
if (criteria.name) {
query.name = new RegExp(criteria.name, 'i');
}
if (criteria.age) {
query.age = criteria.age;
}
return await User.find(query).select('-password');
// ❌ 危险的直接查询
// return await User.find(JSON.parse(criteria));
};
|