hl-api-changelog/changelogs/2026-03/2026-03-22_api_security_hardening.md
API Changelog Bot adf37c7f4b changelog: API安全校验加固通知
全部16个微服务输入校验加固,不影响正常业务流程。
详见 changelogs/2026-03/2026-03-22_api_security_hardening.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 21:20:30 +08:00

88 行
3.0 KiB
Markdown

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

# API 安全校验加固
**日期**: 2026-03-22
**影响范围**: 全部 16 个微服务
**类型**: 安全加固(纯后端,不影响正常业务流程)
---
## 对前端的影响
### 核心结论:正常使用不受影响
本次改动只增加了输入校验,**不改变任何接口路径、参数名、响应格式**。只要前端传入的数据在合理范围内(正常业务操作都是),完全不受影响。
### 可能触发 400 错误的场景(之前不会报错,现在会)
以下情况会返回 `400 Bad Request`,附带具体的校验错误信息:
#### 1. 字符串超长
所有 DTO 的字符串字段现在有长度限制:
- 名称类字段:最长 50-100 字符
- 描述/备注:最长 500-2000 字符
- 富文本内容:最长 10000-100000 字符
- URL 字段:最长 500-1000 字符
**前端建议**:如果有 `<textarea>` 或富文本编辑器,建议前端也加上 `maxlength` 限制,避免用户输入超长内容后提交失败。
#### 2. 数值范围
- 所有金额字段:不允许负数(`@DecimalMin("0")`
- 分页 `pageSize`:最大 100超过自动截断为 100
- 评分 `rating`:必须 1-5
- 人数字段:`adultCount >= 1``childCount >= 0`
#### 3. 列表数量限制
- 出行人 `travelers`:最多 50 人
- 图片列表 `images`:最多 9-20 张
- 视频列表 `videos`:最多 3 个
- 标签列表 `tags`:最多 20-50 个
#### 4. 枚举字段格式
以下字段现在必须严格匹配指定值:
- `refundType`:只能是 `FULL``PARTIAL`
- `action`(退款审核):只能是 `APPROVE``REJECT`
- `sortDir`:只能是 `asc``desc`
#### 5. 小程序端 DTO 校验
所有小程序 API`/mp/**`)现在启用了 `@Valid` 校验:
- `phone`:必须匹配 `^1\d{10}$`11位手机号
- `code`(登录码):不能为空
- `content`(评价/反馈):不能为空,最长 2000-5000 字
---
## 不影响前端的后端内部加固
以下改动完全在后端内部,前端无感知:
| 加固项 | 说明 |
|--------|------|
| 退款并发锁 | Redis 分布式锁防止重复退款 |
| 法大大回调签名验证 | HMAC-SHA256 签名校验 |
| 资源状态修改角色校验 | 仅 SUPER_ADMIN 可直接改状态 |
| 定时任务 Bean 白名单 | 防止执行非授权代码 |
| 文件预览 XSS 防护 | OSS 域名白名单 + HTML 转义 |
| 限流器 IP 防伪造 | 优先使用 X-Real-IP |
| 2FA 端点限流 | 5次/分钟/IP |
| 退款/支付角色校验 | 需要 ADMIN/SUPER_ADMIN/FINANCE 角色 |
| 折扣上限 | 折扣不能等于总价(防 100% 免单) |
| 支付幂等 | Redis 防重复提交 |
| 公式引擎沙箱 | 关键词黑名单 + 循环上限 |
---
## 400 错误响应格式
校验失败时返回格式不变:
```json
{
"code": 400,
"message": "参数校验失败",
"data": {
"fieldName": "具体的错误提示(中文)"
}
}
```
**前端建议**:如果尚未统一处理 400 错误,建议在请求拦截器中对 400 状态码做 toast 提示,展示 `data` 中的第一条错误信息。