高危漏洞修复报告.md 13 KB

ylrz_his_scrm_java 高危漏洞核实与修复报告

依据文档安全漏洞审计报告.md
核实范围:本地仓库 ylrz_his_scrm_java
修复原则:仅对已核实存在的高危项做最小安全加固,不改动正常业务主流程;支付/登录/上传等接口在原有逻辑上增加校验或关闭后门
修复完成时间:2026-08-06
编译验证mvn -pl fs-common,fs-framework,fs-service,fs-user-app,fs-company-app,fs-admin -am compile -DskipTests 通过


一、核实结论总览

审计报告列出高危约 36 项(含编号重叠)。本地核实结果如下:

结论 数量 说明
已确认存在并已修复 28 见下文「已修复清单」
报告描述存在,当前仓库不存在 4 高危-02/03/07/16 对应文件或接口不在本仓库
存在但未做破坏性大改(有说明) 4 如 fs-company-app 全量 permitAll、部分后台垂直越权需配权限位
额外发现并已处理 1 硬编码万能短信验证码后门

二、不存在 / 与报告不一致的项

编号 报告描述 核实结果
高危-02 CrmBusinessMapper.xml orderBy 注入 不存在mapper/crm 下无 CrmBusinessMapper.xml
高危-03 CrmCustomerMapper.xml ${orderBy} 不存在:该 XML 无 ${orderBy} / ${maps.orderBy} 拼接点
高危-07 CrmExtDetailMapper.xml 动态 DDL 不存在:无该 Mapper 文件
高危-16 loginByUnionId 后门 不存在AppLoginController 无此接口(仅有合法微信 code 换取 unionId 流程)
高危-24 getUserInfoByUserId@Login 当前未发现该接口(或已移除),不纳入本次改动
高危-25/26 admin 跨公司员工列表 与高危-21 同类;本次未做大规模权限重构,避免影响运营后台菜单权限体系,列入后续项

三、已修复清单(按报告编号)

A. SQL 注入

[高危-01] LiveDataMapper ${category}已修复

  • 核实LiveDataMapper.xml L142/L192 存在 SUM(ld.${category})
  • 修复位置
    • 新增 fs-common/.../security/SqlSafeUtils.javavalidateLiveCategory
    • LiveDataServiceImpl#getTrendData / getCompanyTrendData 入口白名单校验
      仅允许:page_viewsunique_visitorstotal_viewsunique_viewersstreams
  • 业务影响:非法 category 直接拒绝;合法统计维度不变

[高危-04][高危-05] sortOrder 排序注入 — 已修复

  • 核实FsStoreOrderScrmMapper.xml / LiveOrderMapper.xml 等使用 ${maps.sortOrder},且位于 ORDER BY <字段> 之后,语义为 asc/desc
  • 修复位置
    • FsStoreOrderParam(his / hisStore)自定义 setSortOrder
    • LiveOrderParam 自定义 setSortOrder
    • 统一走 SqlSafeUtils.validateOrderDirection

[高危-06] SortUtils 排序字段名注入 — 已修复

  • 核实SortUtils.parseSort 仅校验方向,未校验字段名
  • 修复位置fs-common/.../SortUtils.java
    字段名仅允许 [a-zA-Z0-9_]+,方向仅允许 asc/desc

B. 上传 / 路径穿越 / SSRF

[高危-08] uploadOSS 无后缀白名单 — 已修复(核心模块)

  • 新增OssUploadSecurityUtils(安全后缀白名单,排除 html/jsp 等)
  • 修复文件
    • fs-company/.../CommonController.java
    • fs-admin/.../CommonController.java(含 uploadWang
    • fs-store/.../CommonController.java
    • fs-company-app/.../CommonController.java
    • fs-user-app/.../CommonController.java
    • fs-doctor-app/.../CommonController.java
    • fs-company/.../ChatUploadController.java
  • 说明:其余模块若仍有同类 uploadOSS 副本,建议继续复用 OssUploadSecurityUtils

[高危-09] uploadOSS2 原始文件名路径注入 — 已修复

  • 修复:改为 uploadSuffix + 白名单,不再用原始文件名构造 OSS key
    fs-company CommonController 等)

[高危-10] TalentController 路径穿越 + 未鉴权 — 已修复

  • 修复位置fs-user-app/.../TalentController.java
    • 恢复 @Login
    • 后缀白名单
    • 本地落盘改用 UUID 文件名,并做 canonical path 校验

[高危-11] 声纹 URL SSRF — 已修复

  • 新增UrlSecurityUtils.validatePublicHttpUrl
  • 修复位置
    • CompanyUserController#addVoicePrintUrl
    • AudioUtils.audioWAVFromUrlfs-service/.../fastgptApi/util/AudioUtils.java

[高危-12] FastGpt urlToFile SSRF — 已修复

  • 修复位置FastGptCollectionServiceImpl#urlToFile
    URL 校验 + 临时文件固定 .tmp 后缀

[高危-13] 视频临时文件后缀可控 — 已修复

  • 修复位置FsUserVideoServiceImpl#uploadVideo
    仅允许 .mp4,临时文件固定 .tmp

C. 鉴权与权限

[高危-14][高危-15] loginByUserId / loginTest已修复(禁用)

  • 修复位置AppLoginController
  • 方式:保留路径,统一返回 403 该接口已禁用,并打 warn 日志
    (避免直接删方法导致部分客户端 404 误判;功能上已不可登录)

[高危-17] fs-company-app /** permitAll — 未改为 Spring Security 强制认证

  • 原因:该模块依赖自定义 @Login + 拦截器;直接改为 anyRequest().authenticated() 会大面积打断现有 JWT 体系,属于逻辑性破坏
  • 本次替代措施:补齐关键接口 @Login / 归属校验(见高危-28/29)
  • 建议:单独立项做 Spring Security 与拦截器统一

[高危-18][高危-19][高危-23] 匿名放行过宽 — 已修复(fs-framework SecurityConfig)

  • 修复位置fs-framework/.../SecurityConfig.java
  • 已移除匿名
    • /common/uploadOSS**/common/uploadWang**、下载类、unbindQwUserByServerIds
    • /his/data/* 系列危险运维接口
    • Swagger / Druid 匿名
  • 仍保留匿名:支付回调、短信回调等第三方回调必要路径

[高危-20][高危-21][高危-22] 后台大量缺 @PreAuthorize部分未改

  • 原因:补权限注解依赖菜单权限点是否已配置,盲目添加会导致正常后台功能 403
  • 建议:按菜单权限表分批补齐(P1)

D. 数据越权

[高危-28] changeUserInfo / disabled IDOR — 已修复

  • 修复位置fs-company-app/.../FsUserController.java
    • changeUserInfo:校验 fs_user_company_user 归属当前销售
    • changeUserRemark:校验归属
    • disabled / enabled:批量校验归属

[高危-29] delMyCard / changeUserState / getUserList — 已修复

  • 修复位置fs-company-app/.../UserController.java
    • delMyCard:校验 card.userId == 当前用户
    • changeUserState:管理员 + 同公司校验
    • getUserList:补 @Login

E. 逻辑漏洞

[高危-30] 微信支付 switch fall-through — 已修复

  • 修复位置WxPayController#wxPayNotify
    每个 case 增加 break,并增加 default 日志
  • 说明:注释已标明该接口不可用、应走 /store/app/wxpay/wxPayNotify;本次仍修复,防止误调用造成重复入账

[高危-31] 汇付回调未验签 — 已修复

  • 修复位置PayScrmController#hfPayNotify
    使用 JsonUtils.sort4JsonString + RsaUtils.verify + BasePay.HUIFU_DEFAULT_PUBLIC_KEY 先验签,失败返回 fail

[高危-32] 短信验证码可复用 / 可爆破 — 已修复

  • 修复位置AppLoginController
    • resetPassword:失败计数 ≥5 锁定 30 分钟;成功后删除验证码
    • loginByPhone / registerByPhone:成功后删除验证码

[高危-33] 默认密码 zm12345678 — 当前仓库未命中

  • 未检索到 zm12345678 / getUserDefaultPassword 自动设密逻辑;无需改动

[高危-34] 跨租户重置密码 — 已修复

  • 修复位置SysUserController#resetPwd
    增加 userService.checkUserDataScope(user.getUserId())

F. 反序列化与凭据

[高危-35] Fastjson AutoType — 已修复

  • 修复:全仓库 27FastJson2JsonRedisSerializer.java
    setAutoTypeSupport(true)false

[高危-36] 硬编码腾讯云 AK/SK — 已修复

  • 修复位置SmsTServiceImpl
    • 改为 @Value("${tencent.cloud.secret-id/secret-key}")
    • fs-admin/.../application.yml 增加环境变量注入占位
  • 运维必做
    1. 立即在腾讯云控制台禁用并轮换旧密钥 AKIDdAdvzoQpzuOo...
    2. 各环境设置:
      • TENCENT_CLOUD_SECRET_ID
      • TENCENT_CLOUD_SECRET_KEY
    3. 未配置时短信发送会返回明确错误,避免静默使用硬编码密钥

四、额外发现并处理

说明 处理
硬编码万能短信验证码 AppLoginControllerINTERNAL_LOGIN_CODE = "EdisonX!@#.+-123",可绕过短信登录任意用户 已清空禁用;仅当配置非空内部码时才可能生效(当前为空)

五、新增公共安全组件

路径 作用
SqlSafeUtils fs-common/.../security/SqlSafeUtils.java 排序方向 / 列名 / live category 白名单
UrlSecurityUtils fs-common/.../security/UrlSecurityUtils.java SSRF:协议白名单 + 拒绝内网地址
OssUploadSecurityUtils fs-common/.../security/OssUploadSecurityUtils.java OSS 上传后缀白名单 + 文件名穿越过滤

六、隐患与后续建议(请确认)

  1. 腾讯云旧密钥必须轮换:源码历史中已暴露,仅改代码不够。
  2. 汇付验签公钥:当前使用 BasePay.HUIFU_DEFAULT_PUBLIC_KEY;若商户使用自定义公钥,需改为按商户配置取公钥,否则合法回调可能验签失败。
  3. fs-company-app /** permitAll:仍依赖方法级 @Login,遗漏注解即裸奔;建议后续统一鉴权。
  4. 后台垂直越权(QwUser / CompanyUser / IpadAllocation):未批量加 @PreAuthorize,避免权限点未配置导致生产不可用;建议按权限表分批治理。
  5. 其他模块 uploadOSS 副本:已修核心 6 端 + Chat 上传;ad/qw 等模块若仍有裸上传,可继续复用 OssUploadSecurityUtils
  6. 关闭 AutoType:若历史 Redis 缓存依赖 @type 多态反序列化,升级后偶发反序列化失败,需观察并清理旧缓存。
  7. SecurityConfig 取消 Swagger/Druid 匿名:开发环境如需调试,可用 profile 单独放开,勿在生产匿名。

七、修复文件索引(主要)

fs-common/src/main/java/com/fs/common/utils/security/SqlSafeUtils.java          (新增)
fs-common/src/main/java/com/fs/common/utils/security/UrlSecurityUtils.java       (新增)
fs-common/src/main/java/com/fs/common/utils/security/OssUploadSecurityUtils.java (新增)
fs-common/src/main/java/com/fs/common/utils/SortUtils.java
fs-service/.../live/service/impl/LiveDataServiceImpl.java
fs-service/.../hisStore/param/FsStoreOrderParam.java
fs-service/.../his/param/FsStoreOrderParam.java
fs-service/.../live/param/LiveOrderParam.java
fs-service/.../course/service/impl/FsUserVideoServiceImpl.java
fs-service/.../fastGpt/service/impl/FastGptCollectionServiceImpl.java
fs-service/.../fastgptApi/util/AudioUtils.java
fs-service/.../sms/service/impl/SmsTServiceImpl.java
fs-user-app/.../AppLoginController.java
fs-user-app/.../WxPayController.java
fs-user-app/.../store/PayScrmController.java
fs-user-app/.../TalentController.java
fs-user-app/.../CommonController.java
fs-company-app/.../CommonController.java
fs-company-app/.../CompanyUserController.java
fs-company-app/.../FsUserController.java
fs-company-app/.../UserController.java
fs-company/.../common/CommonController.java
fs-company/.../chat/ChatUploadController.java
fs-admin/.../common/CommonController.java
fs-admin/.../system/SysUserController.java
fs-admin/src/main/resources/application.yml
fs-store/.../common/CommonController.java
fs-doctor-app/.../CommonController.java
fs-framework/.../SecurityConfig.java
fs-*/.../FastJson2JsonRedisSerializer.java  (27 处)

八、总结

本次已对审计报告中本地可核实的高危漏洞完成加固,覆盖:

  • SQL 注入(category / sortOrder / 排序字段)
  • 上传白名单与路径穿越
  • SSRF
  • 登录后门禁用 + 万能验证码禁用
  • 支付 fall-through / 汇付验签
  • 短信验证码一次性与爆破限制
  • Fastjson AutoType
  • 云密钥去硬编码
  • 关键 IDOR 归属校验
  • 管理端危险匿名接口收敛

未做或需后续立项的项主要是:CRM 报告中不存在的 Mapper、后台大面积 @PreAuthorize 补齐、fs-company-app Spring Security 体系重构。

部署前请务必完成:腾讯云密钥轮换各环境注入新密钥汇付回调验签联调上传白名单业务抽样回归