Files
hzdyjs/问题整改/20261026-安全扫描整改说明.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

5.2 KiB
Raw Permalink Blame History

2026-10-26 安全扫描整改说明

背景:杭州市网安对生产环境进行安全扫描。本次对严重、高危、中危问题做代码级整改;Snail-Job 生产已下线,不在本次范围。 后端 mvn -o compile 全量通过;前端改动文件无新增类型错误。

一、上线前必须执行

项 说明
SQL backend/script/sql/update/update_20261026_workflow_permission.sql:新增工作流管理按钮权限(workflow:definition:list/edit、workflow:instance:manage、workflow:task:manage),并自动授给已拥有「流程定义 / 流程实例 / 待办任务」父菜单的角色。执行后相关用户需重新登录。
配置 application.yml 新增 security.cors-allowed-origins(默认放行 *.hzdyjsxy.cn 与 localhost),若有其它域名访问后端须补充;user.password.ipMaxRetryCount: 30;sa-token.jwt-secret-key 已换成随机值。
nginx 必须向后端传递真实客户端 IP(X-Forwarded-For / X-Real-IP),否则按 IP 的登录失败锁定失效。

二、整改清单

严重

问题 整改
工作流 SpEL 表达式注入可执行系统命令(T(java.lang.Runtime)) 新增 SafeSpelHelper / SafeExpressionStrategies,启动时替换 warm-flow 内置 SpEL 策略:禁止类型引用 T()、new、反射与 getClass/forName/exec/getBean 等方法,仅允许对值类型与 org.dromara 业务 Bean 调用
工作流管理接口无权限控制 流程定义全部接口、实例运行/已完成/删除/激活/挂起/变量/作废、全部待办/已办/修改办理人加权限码;/warm-flow/** 设计器接口按读写加权限;删除实例、撤销流程要求必须是发起人或具备管理权限
社团活动列表 SQL 注入 ${params.dataScope} Mapper 改为 #{} + foreach 的类型化参数;Service 先清除请求中 ds*/dataScope 参数再写入

高危

问题 整改
文件 ossId 越权访问 学生账号只能访问本人或教职工上传的文件;预签名链接最长 1 小时;异常不回显
登录喷洒 / 账号枚举 账号不存在与密码错误提示一致;同一公网 IP 失败 30 次锁定(内网 IP 不计数)
调试接口暴露 删除 testCoefficient、testVicePresidentData、两个 debug/permission、test/scholarshipTypesStructure、debug/sqlLogs、test-location、勤工助学 debug/{id}
新生录取名册导出无权限 加 zsjy:enrollment:process:export 或 query
学生考核申请越权、篡改分数 学生只能增删改查本人申请;审核字段(教师评分、总分、审核人等)服务端清空;只允许状态 1/2/3 时修改
应聘越权 /apply、/my 强制使用当前登录人;/submit 强制状态为 pending
按学号重置学生密码 改为随机临时密码并踢下线;学院账号只能操作本学院学生;操作日志不记录响应
异常信息回显 SQL/堆栈 GlobalExceptionHandler.safeMessage 过滤含 SQL、类名等技术信息的消息;64 处 R.fail(e.getMessage()) 统一过滤
出国附件任意类型上传 扩展名白名单;Content-Type 按扩展名决定(系统 OSS 上传同步改造),不信任客户端

中危

问题 整改
SSE 任意用户群发 删除 /resource/sse/send、/sendAll(前端未使用,服务端推送不受影响)
CORS 回显任意 Origin 且允许携带凭证 仅放行配置的本校域名
心理咨询预约/爽约限制越权 无管理权限时 studentId 强制为本人
社团报名/签到越权查询 无管理权限时 userId/学号强制为本人
奖学金 /my 越权 无列表权限时 applicantId 强制为本人
参数配置读取初始密码 configKey 仅公开白名单键;sys.user.initPassword 需用户新增/重置密码权限
学生信息完善批量赋值 状态、来源、创建人始终由服务端设置
前端存储型 XSS 新增 web/src/utils/htmlSafe.ts;招聘岗位富文本清洗、简历 PDF 字段转义、报修图片预览去掉 innerHTML
开放重定向 社交登录回调只允许跳转本校域名;报修附件下载仅重定向 http(s) 地址并安全编码文件名
日志泄露 生产关闭 MyBatis StdOut SQL 日志;登录监听不再打印 token;微信下载不再打印带 access_token 的 URL
JWT 默认密钥 更换为随机值

三、遗留与运维事项

  1. 默认密码 Hzdyjsxs123456!@#、Hzdyjs123456!@# 已出现在攻击日志中,需排查并强制修改仍使用默认密码的账号。
  2. 轮换 git 历史中出现过的数据库、Redis、监控、CAS 等密钥;确认数据库、Redis、监控端口不对公网开放。
  3. 实习日志 calendar / monthly-statistics 的 studentId 未做归属校验(需权限码,移动端未调用),后续补充。
  4. 社团成员 approvalFlow/{memberId}、用户导入结果弹窗 dangerouslyUseHTMLString(仅管理员)风险较低,后续处理。
  5. web 端 xljk/consultation/calendar/debug.vue 页面与勤工助学 debug/statistics 调用对应的后端接口已不存在,可删除前端代码。