适用人群:所有Web开发者
学习时长:约1天
重要程度:★★★★★(安全是底线)
一、常见Web攻击
| 攻击类型 | 说明 | 危害等级 |
|---|
| SQL注入 | 通过SQL语句注入获取数据 | ★★★★★ |
| XSS | 跨站脚本攻击 | ★★★★☆ |
| CSRF | 跨站请求伪造 | ★★★★☆ |
| 文件上传漏洞 | 上传恶意文件 | ★★★★☆ |
| 暴力破解 | 穷举密码 | ★★★☆☆ |
| 中间人攻击 | 窃取传输数据 | ★★★★☆ |
二、SQL注入防护
2.1 攻击示例
-- 原始SQL
SELECT * FROM users WHERE username = 'admin' AND password = '123456'
-- 注入攻击
-- 用户输入:admin' OR '1'='1
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = ''
-- 结果:绕过登录,获取所有用户
2.2 防护方法
// PHP - 使用预处理语句(PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
$user = $stmt->fetch();
// Laravel
$user = User::where('username', $username)->where('password', $password)->first();
// ThinkPHP
$user = User::where('username', $username)->where('password', $password)->find();
# Python - SQLAlchemy
user = User.query.filter_by(username=username, password=password).first()
# Flask - 参数化查询
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
// Node.js - Prisma
const user = await prisma.user.findUnique({
where: { username: username }
})
// 参数化查询
db.query("SELECT * FROM users WHERE username = ?", [username])
三、XSS防护
3.1 攻击类型
反射型XSS:恶意脚本通过URL参数注入
存储型XSS:恶意脚本存入数据库
DOM型XSS:前端JS直接操作DOM
3.2 防护方法
<!-- 1. 输出转义 -->
<!-- PHP -->
<?= htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8') ?>
<!-- Vue.js(自动转义) -->
<template>
<div>{{ userInput }}</div> <!-- 自动转义 -->
<div v-html="sanitizedHtml"></div> <!-- 需要手动清理 -->
</template>
<!-- React(自动转义) -->
<div>{userInput}</div> <!-- 自动转义 -->
// 2. Content Security Policy (CSP)
// Nginx配置
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";
// 3. 输入验证
function sanitizeInput(input) {
return input
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
}
四、CSRF防护
4.1 攻击原理
1. 用户登录银行网站,获取Cookie
2. 用户访问恶意网站
3. 恶意网站自动发送请求到银行网站
4. 浏览器自动携带Cookie,请求成功
4.2 防护方法
// Laravel - CSRF Token
// 表单中添加
@csrf
// 中间件验证
Route::middleware('csrf')->group(function () {
// ...
});
// API使用Sanctum
Route::middleware('auth:sanctum')->group(function () {
// ...
});
# Flask - CSRF保护
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
# 表单中添加
<form method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
</form>
# Nginx - SameSite Cookie
add_header Set-Cookie "key=value; SameSite=Strict; Secure; HttpOnly";
五、认证安全
5.1 密码安全
// PHP - 密码加密
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
// 验证
if (password_verify($inputPassword, $hashedPassword)) {
// 密码正确
}
// Laravel
Hash::make($password)
Hash::check($inputPassword, $hashedPassword)
# Python - Werkzeug
from werkzeug.security import generate_password_hash, check_password_hash
hashed = generate_password_hash(password)
check_password_hash(hashed, input_password)
5.2 JWT安全
// JWT最佳实践
const jwt = require('jsonwebtoken')
// 生成Token
const token = jwt.sign(
{ userId: user.id, role: user.role },
SECRET_KEY,
{ expiresIn: '24h' } // 设置过期时间
)
// 验证Token
try {
const decoded = jwt.verify(token, SECRET_KEY)
// Token有效
} catch (err) {
// Token无效或过期
}
5.3 限流防暴力破解
# Nginx限流
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
location /api/auth/login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://backend;
}
}
// Laravel限流
Route::middleware('throttle:5,1')->group(function () {
Route::post('/login', [AuthController::class, 'login']);
});
六、文件上传安全
// Laravel - 文件验证
$request->validate([
'file' => 'required|file|max:10240|mimes:jpg,png,pdf',
]);
// 存储到非Web目录
$path = $request->file('file')->store('uploads', 'local');
// 生成随机文件名
$filename = uniqid() . '.' . $request->file('extension');
# Flask - 文件上传
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
七、HTTPS配置
# Nginx HTTPS配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.pem;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}
# HTTP跳转HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
八、安全头配置
# Nginx安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self';" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
九、安全检查清单
输入验证
✅ 所有用户输入都需要验证
✅ 白名单验证优于黑名单验证
✅ 长度限制、类型限制、格式验证
输出编码
✅ HTML输出转义
✅ JavaScript输出转义
✅ URL参数编码
✅ SQL参数化查询
认证安全
✅ 密码加密存储(bcrypt/argon2)
✅ JWT设置过期时间
✅ 登录失败限流
✅ 敏感操作二次验证
传输安全
✅ 全站HTTPS
✅ HSTS启用
✅ Cookie设置Secure和HttpOnly
文件安全
✅ 文件类型白名单验证
✅ 文件大小限制
✅ 随机文件名
✅ 存储到非Web目录
配置安全
✅ 关闭调试模式
✅ 删除默认页面
✅ 最小权限原则
✅ 定期更新依赖
学习建议
- 理解OWASP Top 10,这是最常见的Web安全风险
- 所有输入都要验证,不要信任任何用户输入
- 使用框架的安全功能,如Laravel的CSRF保护
- 定期更新依赖,修复已知漏洞
- 安全意识比技术更重要,时刻保持警惕