类型:数据导出问题 严重性:严重 状态:5.1.已关闭(复测通过)
| 问题描述 | 导出能导出全网的数据,没有做权限控制 |
|---|---|
| 一级模块 | 项目信息填报 |
| 二级模块 | / |
| 涉及类型 | 全部类型 |
| 是否阻断流程 | 是 |
| 处理人员 | 洪陈解 |
| 复测情况 | 复测通过 |
src/views/projectMaintain/manage/planPool.vue 第1088-1120行 _export():把当前 searchForm(含用户是否勾选省份/地市,可能为空)直接传给导出接口,导出接口地址为 src/api/projectMaintain/implement.js 中 exportProjectImplByIdList / exportFileType(URL 前缀 /so/oms/in/so-pf-new-energy-th/ePjpl/...)——经在 730backup 后端仓库全文搜索,未找到该 URL 段 ePjpl 对应的任何 Controller 实现,判断该按钮实际调用的是历史遗留/未纳入本仓库的旧版微服务地址。src/main/java/cn/csg/so/oms/in/newenergy/project/controller/NewNePjController.java 第140-172行:exportProject(HttpServletResponse response, GetProjectAdjustQueryParam condition)src/main/java/cn/csg/so/oms/in/newenergy/project/appservice/ProjectImplAppService.java 第220-236行:selectAll(GetProjectAdjustQueryParam param) —— 仅当 param.getProjectApply() 非空时,才会用 UserUtils.getUser().getUserId() 查该用户关联的场站/项目 ID 列表并收窄查询范围;该字段同样是客户端可选传参,前端导出调用若不传,则不做任何用户范围限制,与 row3 的 buildQueryParams() 是同一套设计模式ProjectImplAppService.java 第220-236行 selectAll() 方法入口(导出与列表查询共用同一收口点)导出接口与列表查询接口(row3)共享同一个"客户端传了范围参数才过滤,不传就是全网"的设计缺陷,导出场景风险更高——因为导出结果是完整 Excel 文件,一旦泄露影响面更大。修复思路与 row3 一致,但导出接口必须强制启用该收口,不能像列表查询那样只是"建议式"参数:
public IPage<NePjImplVO> selectAll(GetProjectAdjustQueryParam param) {
...
// 修复:导出场景强制启用用户数据范围收口,不依赖 projectApply 是否传入
UserUtils.User user = UserUtils.getUser();
if (!isAdminOrScienceInstitute(user)) {
param.setProjectApply("1"); // 强制置为需要按用户范围过滤
}
//判断是否场站人员标识
if (StringUtils.isNotBlank(param.getProjectApply())) {
List<String> allPlanIdList = new ArrayList<>();
String userId = UserUtils.getUser().getUserId();
...
}
...
}
另外,导出接口 exportProject() 目前使用字符串拼接方式构造 type in ('...') SQL(ProjectImplAppService.java 约第268-283行),存在与本条无直接关系但同一方法内可顺带修复的 SQL 注入风险,建议改为 MyBatis <foreach> 参数化写法。
planPool.vue 的 exportProjectImplByIdList)指向一个在 730backup 后端仓库中找不到的历史 URL,无法在本分支内直接核实其权限校验逻辑;本方案基于同仓库内功能等价、确认存在的 exportProject/selectAll 路径给出根因与修复设计,建议同时核实该导出按钮实际部署时具体路由到哪个微服务,避免遗漏修复范围。