
OWASP API Top 10 防护

1. 对象级授权失效
// 始终将查询范围限定为已认证用户
app.get('/orders/:id', auth, async (req, res) => {
const order = await db.order.findFirst({
where: { id: req.params.id, userId: req.user.id }
})
if (!order) return res.status(404).json({ error: 'Not found' })
return res.json(order)
})

2. 输入验证
import { z } from 'zod'
const Schema = z.object({
title: z.string().min(1).max(200).trim(),
tags: z.array(z.string().max(50)).max(10).default([]),
})
app.post('/posts', auth, async (req, res) => {
const result = Schema.safeParse(req.body)
if (!result.success) return res.status(400).json({ errors: result.error.flatten() })
return res.status(201).json(await db.post.create({ data: result.data }))
})

3. 速率限制 + 安全标头
import helmet from 'helmet'
import rateLimit from 'express-rate-limit'
app.use(helmet({ hsts: { maxAge: 31536000, includeSubDomains: true, preload: true } }))
app.use('/api/', rateLimit({
windowMs: 15 * 60 * 1000, max: 100,
keyGenerator: (req) => req.user?.id ?? req.ip,
}))
app.use('/api/auth/', rateLimit({ windowMs: 3600_000, max: 10 }))
4. SQL 注入
// 始终使用参数化查询或 ORM
await db.query('SELECT * FROM users WHERE email = $1', [email])
// ORM(Prisma/TypeORM):默认安全
const user = await db.user.findFirst({ where: { email } })
5. 最小权限数据暴露
const user = await db.user.findUnique({
where: { id },
select: { id: true, email: true, name: true }
// password, ssn, creditCard: 绝不选择
})
-> 使用 Token 生成器 生成令牌。