Files
hzdyjs/问题整改/20260922-安全扫描修改.md
“wuzhen”andCursor da8d332fac fix(security): 修复网安扫描相关严重/高危/中危漏洞并加固学生密码重置
关闭工作流 SpEL 命令执行与社团活动 SQL 注入,补齐越权、调试接口、登录喷洒和异常回显等问题;学生密码改为随机临时密码,Web/移动端支持复制。

Constraint: 流程发起/办理接口保持仅登录校验,避免影响请假审批
Rejected: 开启验证码 | Web/移动端登录页均未实现,开启会导致无法登录
Confidence: high
Scope-risk: broad
Not-tested: 生产环境与社团社长/指导老师视角
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-26 13:44:51 +08:00

194 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 20260922 安全扫描修改
> 针对扫描报告中免登录接口暴露、敏感信息泄露及可写风险的整改记录。
> 扫描样例:`GET /prod-api/zsjy/enrollment/info/query?examNumber=123456` 可免登返回身份证、手机号等。
## 一、本次处理范围
| 优先级 | 项 | 处理结果 |
|--------|----|----------|
| P0 | `POST /rs/init/update-menu` 未授权改菜单 | **已整改** |
| P0 | `/rs/init/menu`、`/clear` 登录即可写删菜单 | **已整改**(类级 `system:menu:edit`,见 `P0-rs-init全接口权限锁死整改说明.md`) |
| P0 | `SysUserController` 权限注解被注释 | **已整改**(见 `P0-SysUser权限注解恢复整改说明.md`) |
| P0 | `SysRole` / `SysTenant` 权限注解被注释 | **已整改**(见 `P0-SysRole-SysTenant权限注解恢复整改说明.md`) |
| P0 | `SysOss` 管理越权 + 上传无白名单 | **已整改并复测通过**(见 `P0-SysOss权限与上传白名单整改说明.md`;学生角色仍误授 `system:oss:*` 属配权问题) |
| P1 | 招生 query/myStatus IDOR + 完整 PII | **已整改**(见 `P1-招生报名查询双因子与脱敏整改说明.md`) |
| P1 | 毕业生按学号/身份证 IDOR | **已整改**(见 `P1-毕业生信息权限恢复整改说明.md`) |
| P1 | 学生信息 list/详情/导出垂直越权 | **已整改并复测通过**(见 `P1-学生信息权限恢复整改说明.md`;学生角色仍误授 `studentMsg:*` 属配权问题) |
| P0 | Bucket 密码重置 + OSS 配置密钥面 | **已整改并复测通过**(见 `P0-Bucket密码与OSS配置权限恢复整改说明.md`) |
| P0 | `SysClient` 客户端密钥面权限注释 | **已整改并复测通过**(见 `P0-SysClient权限恢复整改说明.md`) |
| P1 | 贫困认定申请/审批垂直越权 | **已整改并复测通过**(见 `P1-贫困认定权限恢复整改说明.md`) |
| P1 | 心理健康测评/预约垂直越权 | **已整改并复测通过**(见 `P1-心理健康权限恢复整改说明.md`) |
| P1 | 奖助学金申请/配置垂直越权 | **已整改并复测通过**(见 `P1-奖助学金权限恢复整改说明.md`) |
| P1 | 勤工俭学岗位/申请垂直越权 | **已整改并复测通过**(见 `P1-勤工俭学权限恢复整改说明.md`;学生角色仍误授部分 `workStudy*` 属配权问题) |
| P1 | 出国研修/培训垂直越权 | **已整改并复测通过**(见 `P1-出国研修培训权限恢复整改说明.md`) |
| P1 | 宿舍/假期留宿/操行分等垂直越权 | **已整改并复测通过**(见 `P1-宿舍假期留宿权限恢复整改说明.md`;学生角色仍误授大量宿舍相关权限,属配权问题) |
| P1 | 招生就业模块(录取流程/实习等)垂直越权 | **已整改并一次复测通过**(见 `批量权限恢复与Redis清理说明.md`) |
| P1 | 业务模块剩余注释权限(财务/物业/社团等) | **源码已清零并一次复测通过**(见 `批量权限恢复与Redis清理说明.md`) |
| 运维 | Redis 登录 Session 坏缓存 | **已清理**(DB8 Authorization/online_tokens) |
| 配权 | 学生角色误授管理权限 | **开发库已执行并复测通过**(删约 99 条;见 `收紧学生角色过宽权限.sql`) |
| P0 | Swagger `/api-docs`、`/swagger-ui/**` | **已下线** |
| P0 | Demo `/demo/mail/**`、`/demo/queue/delayed/**` | **已下线(运行包不再引入)** |
| P0 | 招生 5 个免登接口(含扫描点名 `query`) | **已整改**(须登录) |
| P1 | `GET /cas/accessToken` 密钥暴露与日志明文 | **部分整改**(前端去 secret + 日志脱敏;后端 secret 外置待做) |
| P1 | `POST /rs/application/submit` 匿名滥投 | **已整改**(须登录) |
---
## 二、已完成修改明细
### 1. P0:`POST /rs/init/update-menu` 须登录
**问题**:标注 `@SaIgnore`,未登录即可删改 `sys_menu` / `sys_role_menu`。
**修改**:
- 移除 `@SaIgnore`
- 增加 `@SaCheckPermission("system:menu:edit")`
**文件**:
- `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/controller/RsInitController.java`
**验证**:未带 Token → 401;无 `system:menu:edit` → 无权限。
---
### 2. P0:Swagger / api-docs 下线
**问题**:`security.excludes` 放行文档路径,且 `springdoc` 开启,便于枚举全量接口。
**修改**:
- `springdoc.api-docs.enabled` / `swagger-ui.enabled` → `false`
- 从 `security.excludes` 移除 `/api-docs`、`/swagger-ui/**`、`/v3/api-docs/**`、`/webjars/**` 等
**文件**:
- `backend/ruoyi-admin/src/main/resources/application.yml`
**验证**:访问 `/prod-api/swagger-ui.html`、`/prod-api/api-docs` 不可用。
---
### 3. P0:Demo 模块下线
**问题**:`ruoyi-demo` 打入运行包,邮件、延迟队列等接口带 `@SaIgnore`。
**修改**:注释掉运行路径上所有 `ruoyi-demo` 依赖(admin + 各业务模块),Controller 不再注册。
**文件**:
- `backend/ruoyi-admin/pom.xml`
- `backend/ruoyi-modules/ruoyi-hq/pom.xml`
- `backend/ruoyi-modules/ruoyi-rs/pom.xml`
- `backend/ruoyi-modules/ruoyi-cw/pom.xml`
- `backend/ruoyi-modules/ruoyi-xg/pom.xml`
- `backend/ruoyi-modules/ruoyi-zsjy/pom.xml`
- `backend/ruoyi-modules/ruoyi-jcbt/pom.xml`
- `backend/ruoyi-modules/ruoyi-xskh/pom.xml`
- `backend/ruoyi-modules/ruoyi-bzrkh/pom.xml`
- `backend/ruoyi-modules/ruoyi-aqbw/pom.xml`
**说明**:源码目录 `ruoyi-modules/ruoyi-demo` 仍保留,默认构建/部署不加载。
**验证**:`/prod-api/demo/mail/**`、`/prod-api/demo/queue/delayed/**` → 404。
---
### 4. P0:招生报名相关 5 个接口须登录(扫描报告点名)
**问题**:以下接口标注 `@SaIgnore`,未登录即可访问;其中 `query` 仅凭准考证号即可返回身份证、手机号、住址等敏感信息。
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/zsjy/enrollment/info/query` | 按身份证/准考证查报名 |
| POST | `/zsjy/enrollment/info/submit` | 学生提交报名 |
| GET | `/zsjy/enrollment/info/myStatus` | 查本人报名状态 |
| GET | `/zsjy/enrollment/info/colleges` | 学院列表 |
| GET | `/zsjy/enrollment/info/majors/{collegeId}` | 专业列表 |
**修改**:
- 后端:移除上述 5 个方法的 `@SaIgnore`,走统一登录校验
- 移动端:去掉 `isToken: false`,请求携带 Token
**文件**:
- `backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/ZsjyEnrollmentInfoController.java`
- `mobile/src/api/enrollment.js`
- `mobile/src/pages/enrollment/index.vue`
**影响**:新生报名页须先登录再查询/提交;未带 Token 访问上述接口返回 401。
**验证**:
- 无 Token 访问 `GET /prod-api/zsjy/enrollment/info/query?examNumber=123456` → 401
- 登录后携带 Token 可正常查询/提交
---
### 5. P1:CAS 换票 — 前端去 secret + 日志脱敏
**问题**:
- 前端写死 `CAS_CLIENT_SECRET`(虽未参与换票,但会进浏览器包)
- 后端日志打印含 secret 的完整 URL、access_token、完整 profile
**修改**:
- 删除前端 `CAS_CLIENT_SECRET`;换票仍只调 `GET /cas/accessToken?code=...`
- 前端控制台不再打印含 Token 的响应 body
- `CasController` 日志仅保留 base/client_id/长度等非敏感信息;失败响应不再回传 CAS 原始报文
**文件**:
- `web/src/views/login.vue`
- `backend/ruoyi-admin/src/main/java/org/dromara/web/controller/CasController.java`
- `docs/开发文档/统一身份认证接入说明.md`(同步说明)
**对登录影响**:无(前端本未使用 secret;日志脱敏不改换票逻辑)。
**未做(后续建议)**:
- 后端 `CLIENT_SECRET` 配置外置 + 向 CAS 轮换密钥
- `/cas/accessToken` IP 限流
---
### 6. P1:`POST /rs/application/submit` 须登录
**问题**:`@SaIgnore` + `security.excludes` 放行,可匿名灌简历数据。
**修改**:
- 移除 `@SaIgnore`
- 从 `security.excludes` 删除 `/rs/application/submit`
- 提交时绑定 `applicantId = LoginHelper.getUserId()`
**文件**:
- `backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/controller/RsApplicationController.java`
- `backend/ruoyi-admin/src/main/resources/application.yml`
- `docs/开发文档/API/招聘模块API.md`
**影响**:招聘门户投递须先登录;`/rs/job/public/**` 公开浏览不受影响。
---
## 三、部署与验证清单
1. 重新编译打包后端(demo 依赖变更需完整构建),部署后重启。
2. 前端若已发布含 CAS secret 的旧包,需重新构建发布 `web`。
3. 移动端报名相关改动需重新发布 `mobile`。
4. 抽查:
- [ ] `POST /rs/init/update-menu` 无 Token → 401
- [ ] `/swagger-ui.html`、`/api-docs` 不可用
- [ ] `/demo/mail/**` → 404
- [ ] `GET /zsjy/enrollment/info/query?examNumber=123456` 无 Token → 401
- [ ] 招生 submit / myStatus / colleges / majors 无 Token → 401
- [ ] CAS 统一认证登录仍可用
- [ ] `POST /rs/application/submit` 无 Token → 401;登录后可提交
---
## 四、相关分项说明(可作附录查阅)
| 文档 | 内容 |
|------|------|
| `问题整改/P0-rs-init-update-menu免登整改说明.md` | 菜单更新接口 |
| `问题整改/P0-Swagger与Demo下线整改说明.md` | Swagger / Demo |
| `问题整改/P1-CAS换票密钥与日志脱敏整改说明.md` | CAS |
| `问题整改/P1-rs-application-submit须登录整改说明.md` | 应聘提交 |
---
**文档日期**:2026-09-22
**主题**:安全扫描修改