Koa.js 安全最佳实践
安全概述
Web 应用安全性至关重要,Koa.js 框架虽本身简洁,但需要开发者自行实现各种安全措施。本文将介绍 Koa.js 开发中常见的安全漏洞及防护方案,帮助开发者构建安全的 Web 应用。
身份验证与会话管理
安全的身份验证是应用安全的第一道防线:
- 密码存储:使用 bcrypt 等算法加密存储密码,切勿明文保存
- 会话管理:使用安全的 cookie 设置,启用 httpOnly 和 secure 标志
- Token 机制:JWT Token 设置合理的过期时间,妥善保管密钥
- 多因素认证:敏感操作要求二次验证
安全的密码处理
const bcrypt = require('bcrypt');
const saltRounds = 12;
// 密码加密
async function hashPassword(password) {
return await bcrypt.hash(password, saltRounds);
}
// 密码验证
async function verifyPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
// Koa 中使用示例
router.post('/register', async (ctx) => {
const { username, password } = ctx.request.body;
// 密码强度校验
if (password.length < 8) {
ctx.status = 400;
ctx.body = { error: '密码长度至少8位' };
return;
}
const hashedPassword = await hashPassword(password);
// 存储到数据库...
});
输入验证与过滤
所有用户输入都不可信,必须进行严格验证:
| 验证类型 | 实现方式 | 示例 |
|---|---|---|
| 数据类型 | 强制类型转换 | Number(id) |
| 字符串长度 | 限制最大长度 | max: 1000 |
| 特殊字符 | 转义或过滤 | DOMPurify |
| 格式校验 | 正则或schema | email, phone |
CSRF 防护
跨站请求伪造(CSRF)是一种常见攻击方式:
const csrf = require('koa-csrf');
const koaBody = require('koa-body');
const app = new Koa();
// CSRF 中间件
app.use(new csrf({
invalidTokenStatusCode: 403,
invalidCsrfStatusCode: 403,
expiresIn: 3600
}));
// 需要在 body parser 之后
app.use(koaBody());
// 表单中使用
router.get('/form', async (ctx) => {
ctx.body = `
`;
});
XSS 防护
跨站脚本攻击(XSS)防护要点:
- 输出编码:用户内容输出时进行 HTML 转义
- Content Security Policy:设置 CSP 头限制脚本执行
- HttpOnly Cookie:防止 JavaScript 读取敏感 cookie
- 输入过滤:过滤或拒绝危险标签和属性
安全响应头
const helmet = require('koa-helmet');
app.use(helmet());
// 或者自定义配置
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"]
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true
}
}));
速率限制
防止暴力破解和拒绝服务攻击:
- 登录限流:同一账号密码错误次数限制
- IP 限流:同一 IP 请求频率限制
- 接口限流:敏感接口单独限流
- 验证码:多次失败后要求验证码