Skip to content

SysUserController.java:importUsers未鉴权,可能导致普通用户向数据库导入用户数据 #124

@old6ma

Description

@old6ma

问题描述
在SysUserController.java中的importUsers函数未对当前用户的身份进行权限检查,可能导致普通用户也可以向数据库导入用户数据,具体表现如下:
用户调用importUsers接口:
@Operation(summary = "导入用户") @PostMapping("/import") public Result importUsers(@Parameter(description = "部门ID") Long deptId, MultipartFile file) throws IOException { UserImportListener listener = new UserImportListener(deptId); EasyExcel.read(file.getInputStream(), UserImportVO.class, listener).sheet().doRead(); String msg = listener.getMsg(); return Result.success(msg); }
该函数随后通过importListener的invoke函数并调用UserServiceImpl.java的save函数直接向数据库导入数据:
`@Override
public void invoke(UserImportVO userImportVO, AnalysisContext analysisContext) {
log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(userImportVO));
// 校验数据
StringBuilder validationMsg = new StringBuilder();

    String username = userImportVO.getUsername();
    if (StrUtil.isBlank(username)) {
        validationMsg.append("用户名为空;");
    } else {
        long count = userService.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        if (count > 0) {
            validationMsg.append("用户名已存在;");
        }
    }

    String nickname = userImportVO.getNickname();
    if (StrUtil.isBlank(nickname)) {
        validationMsg.append("用户昵称为空;");
    }

    String mobile = userImportVO.getMobile();
    if (StrUtil.isBlank(mobile)) {
        validationMsg.append("手机号码为空;");
    } else {
        if (!Validator.isMobile(mobile)) {
            validationMsg.append("手机号码不正确;");
        }
    }

    if (validationMsg.length() == 0) {
        // 校验通过,持久化至数据库
        SysUser entity = userConverter.importVo2Entity(userImportVO);
        entity.setDeptId(deptId);   // 部门
        entity.setPassword(passwordEncoder.encode(SystemConstants.DEFAULT_PASSWORD));   // 默认密码
        // 性别翻译
        String genderLabel = userImportVO.getGender();
        if (StrUtil.isNotBlank(genderLabel)) {
            Integer genderValue = (Integer) IBaseEnum.getValueByLabel(genderLabel, GenderEnum.class);
            entity.setGender(genderValue);
        }

        // 角色解析
        String roleCodes = userImportVO.getRoleCodes();
        List<Long> roleIds = null;
        if (StrUtil.isNotBlank(roleCodes)) {
            roleIds = roleService.list(
                            new LambdaQueryWrapper<SysRole>()
                                    .in(SysRole::getCode, roleCodes.split(","))
                                    .eq(SysRole::getStatus, StatusEnum.ENABLE.getValue())
                                    .select(SysRole::getId)
                    ).stream()
                    .map(role -> role.getId())
                    .collect(Collectors.toList());
        }


        boolean saveResult = userService.save(entity);
        if (saveResult) {
            validCount++;
            // 保存用户角色关联
            if (CollectionUtil.isNotEmpty(roleIds)) {
                List<SysUserRole> userRoles = roleIds.stream()
                        .map(roleId -> new SysUserRole(entity.getId(), roleId))
                        .collect(Collectors.toList());
                userRoleService.saveBatch(userRoles);
            }
        } else {
            invalidCount++;
            msg.append("第" + (validCount + invalidCount) + "行数据保存失败;<br/>");
        }
    } else {
        invalidCount++;
        msg.append("第" + (validCount + invalidCount) + "行数据校验失败:").append(validationMsg + "<br/>");
    }
}

`
其中整个调用链中没有进行权限检查,可能存在普通用户也可以随意向数据库中导入用数据的情况,影响数据安全性

建议添加以下权限检查:
@PreAuthorize("@ss.hasPerm('sys:role:edit')")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions