安全, HTTPS·
Web 安全最佳实践
保护你的网站和用户免受常见安全威胁
Web 安全是每个开发者都必须关注的重要话题。本文介绍常见的 Web 安全威胁和防护措施。
常见安全威胁
XSS(跨站脚本攻击)
XSS 攻击通过在网页中注入恶意脚本来窃取用户数据。
<!-- 危险:直接插入用户输入 -->
<div id="user-content"></div>
<script>
document.getElementById('user-content').innerHTML = userInput;
</script>
<!-- 安全:对用户输入进行转义 -->
<div id="user-content"></div>
<script>
document.getElementById('user-content').textContent = userInput;
</script>
防护措施:
- 输入验证和转义
- 使用 Content Security Policy(CSP)
- HttpOnly Cookie
// 使用 DOMPurify 清理 HTML
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirtyInput);
CSRF(跨站请求伪造)
CSRF 攻击诱使用户在不知情的情况下执行非预期的操作。
防护措施:
- 使用 CSRF Token
- SameSite Cookie 属性
- 验证 Referer 头
// 前端:CSRF Token
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('/api/update', {
method: 'POST',
headers: {
'X-CSRF-Token': csrfToken,
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
// 后端:验证 Token(示例)
app.use((req, res, next) => {
const token = req.headers['x-csrf-token'];
if (token !== req.session.csrfToken) {
return res.status(403).send('Invalid CSRF token');
}
next();
});
SQL 注入
SQL 注入通过恶意 SQL 语句攻击数据库。
-- 危险
SELECT * FROM users WHERE name = '" + userInput + "';
-- 安全:使用参数化查询
SELECT * FROM users WHERE name = ?;
// 安全:使用参数化查询
const query = 'SELECT * FROM users WHERE name = ?';
db.query(query, [userInput]);
HTTPS 和 SSL/TLS
为什么需要 HTTPS
- 加密数据传输
- 验证服务器身份
- 保护数据完整性
- SEO 排名提升
配置 HTTPS
# Nginx HTTPS 配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# 启用 HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
# HTTP 到 HTTPS 重定向
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
免费 SSL 证书
使用 Let's Encrypt 获取免费 SSL 证书:
# 安装 Certbot
sudo apt-get install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期
sudo certbot renew --dry-run
Content Security Policy(CSP)
CSP 限制资源加载来源,防止 XSS 攻击:
<meta http-equiv="Content-Security-Policy" content="
default-src 'self';
script-src 'self' 'unsafe-inline' https://trusted.cdn.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
connect-src 'self' https://api.example.com;
">
// 通过 HTTP 头设置
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'
安全 Headers
重要安全 Headers
// 安全 Headers 配置
app.use((req, res, next) => {
// X-Frame-Options: 防止点击劫持
res.setHeader('X-Frame-Options', 'DENY');
// X-Content-Type-Options: 防止 MIME 类型嗅探
res.setHeader('X-Content-Type-Options', 'nosniff');
// X-XSS-Protection: XSS 过滤
res.setHeader('X-XSS-Protection', '1; mode=block');
// Strict-Transport-Security: 强制 HTTPS
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
// Content-Security-Policy: 资源加载策略
res.setHeader('Content-Security-Policy', "default-src 'self'");
next();
});
密码安全
密码哈希
import bcrypt from 'bcryptjs';
// 哈希密码
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(plainPassword, salt);
// 验证密码
const isValid = await bcrypt.compare(plainPassword, hashedPassword);
密码策略
- 最少 8 个字符
- 包含大小写字母、数字和特殊字符
- 定期更换密码
- 使用密码管理器
会话安全
// 安全的 Cookie 设置
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true, // 防止 XSS 访问
secure: true, // 仅通过 HTTPS 传输
sameSite: 'strict', // CSRF 防护
maxAge: 24 * 60 * 60 * 1000 // 1 天过期
}
}));
数据验证
输入验证
import { z } from 'zod';
// 定义验证模式
const userSchema = z.object({
email: z.string().email(),
password: z.string().min(8).regex(/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/),
age: z.number().min(18).max(120)
});
// 验证输入
try {
const validatedUser = userSchema.parse(userInput);
} catch (error) {
console.error('验证失败:', error.errors);
}
输出编码
// HTML 编码
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
安全检查清单
开发阶段
- 输入验证和过滤
- 输出编码
- 参数化查询
- CSRF 保护
- XSS 防护
- 配置 CSP
部署阶段
- 启用 HTTPS
- 配置安全 Headers
- 更新依赖包
- 禁用不必要的功能
- 定期备份
运维阶段
- 监控安全事件
- 定期安全审计
- 及时更新补丁
- 访问控制
- 日志记录
学习资源
保护你的网站,保护你的用户!