fix: 修复sql注入漏洞

This commit is contained in:
fit2cloud-chenyw 2023-09-08 10:20:34 +08:00
parent e1d1d35666
commit 80c4385c5d
9 changed files with 109 additions and 40 deletions

View File

@ -19,10 +19,7 @@ import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.controller.response.ExistLdapUser;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.KeyGridRequest;
import io.dataease.controller.sys.request.SysUserCreateRequest;
import io.dataease.controller.sys.request.SysUserPwdRequest;
import io.dataease.controller.sys.request.SysUserStateRequest;
import io.dataease.controller.sys.request.*;
import io.dataease.controller.sys.response.AuthBindDTO;
import io.dataease.controller.sys.response.RoleUserItem;
import io.dataease.controller.sys.response.SysUserGridResponse;
@ -81,7 +78,7 @@ public class SysUserController {
})
@SqlInjectValidator(value = {"create_time", "u.enabled", "nick_name", "u.dept_id"})
public Pager<List<SysUserGridResponse>> userGrid(@PathVariable int goPage, @PathVariable int pageSize,
@RequestBody KeyGridRequest request) {
@RequestBody UserGridRequest request) {
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
List<SysUserGridResponse> users = sysUserService.query(request);
users.forEach(user -> {
@ -95,9 +92,8 @@ public class SysUserController {
@ApiIgnore
@PostMapping("/userLists")
@SqlInjectValidator({"nick_name", "create_time"})
public List<SysUserGridResponse> userLists(@RequestBody BaseGridRequest request) {
KeyGridRequest keyGridRequest = BeanUtils.copyBean(new KeyGridRequest(), request);
List<SysUserGridResponse> users = sysUserService.query(keyGridRequest);
public List<SysUserGridResponse> userLists(@RequestBody UserGridRequest request) {
List<SysUserGridResponse> users = sysUserService.query(request);
if (CollectionUtils.isEmpty(users)) return users;
users.forEach(user -> {
user.setPassword(null);
@ -113,7 +109,7 @@ public class SysUserController {
@ApiImplicitParam(name = "request", value = "查询条件", required = true)
})
@SqlInjectValidator(value = {"create_time", "u.enabled", "nick_name", "u.dept_id"})
public Pager<List<SysUserGridResponse>> userGrids(@PathVariable String datasetId, @RequestBody KeyGridRequest request) {
public Pager<List<SysUserGridResponse>> userGrids(@PathVariable String datasetId, @RequestBody UserGridRequest request) {
return userGrid(0, 0, request);
}

View File

@ -0,0 +1,19 @@
package io.dataease.controller.sys.request;
import io.dataease.plugins.common.request.KeywordRequest;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class UserGridRequest extends KeywordRequest {
@ApiModelProperty("角色ID列表")
private List<Long> roleIdList;
@ApiModelProperty("组织ID列表")
private List<Long> deptIdList;
@ApiModelProperty("状态")
private List<Integer> enabledList;
}

View File

@ -1,12 +1,13 @@
package io.dataease.ext;
import io.dataease.controller.sys.request.UserGridRequest;
import io.dataease.ext.query.GridExample;
import io.dataease.controller.sys.response.SysUserGridResponse;
import java.util.List;
public interface ExtSysUserMapper {
List<SysUserGridResponse> query(GridExample example);
List<SysUserGridResponse> query(UserGridRequest request);
List<String> ldapUserNames(Integer from);

View File

@ -33,7 +33,7 @@
</resultMap>
<select id="query" parameterType="io.dataease.ext.query.GridExample" resultMap="BaseResultMap">
<select id="query" parameterType="io.dataease.controller.sys.request.UserGridRequest" resultMap="BaseResultMap">
SELECT DISTINCT
u.*,
u.user_id AS id,
@ -42,26 +42,38 @@
FROM
(
select * from sys_user
<if test="extendCondition != null">
<if test="keyword != null">
where
nick_name like concat('%', #{extendCondition} , '%')
nick_name like concat('%', #{keyword} , '%')
or
email like concat('%', #{extendCondition} , '%')
email like concat('%', #{keyword} , '%')
</if>
) u
LEFT JOIN sys_dept d ON d.dept_id = u.dept_id
LEFT JOIN sys_users_roles sur ON sur.user_id = u.user_id
LEFT JOIN sys_role r ON r.role_id = sur.role_id
where 1 = 1
<if test="_parameter != null">
<include refid="io.dataease.ext.query.GridSql.gridCondition"/>
<if test="roleIdList != null and roleIdList.size() > 0">
and r.role_id in
<foreach collection="roleIdList" item="roleId" open='(' separator=',' close=')'>
#{roleId}
</foreach>
</if>
<if test="orderByClause != null">
order by ${orderByClause}
<if test="deptIdList != null and deptIdList.size() > 0">
and d.dept_id in
<foreach collection="deptIdList" item="deptId" open='(' separator=',' close=')'>
#{deptId}
</foreach>
</if>
<if test="orderByClause == null">
order by u.update_time desc
<if test="enabledList != null and enabledList.size() > 0">
and u.enabled in
<foreach collection="enabledList" item="en" open='(' separator=',' close=')'>
#{en}
</foreach>
</if>
</select>
<select id="queryRole" resultMap="sysUserRole">

View File

@ -65,11 +65,9 @@ public class SysUserService {
private AuthUserService authUserService;
public List<SysUserGridResponse> query(KeyGridRequest request) {
String keyWord = request.getKeyWord();
GridExample gridExample = request.convertExample();
gridExample.setExtendCondition(keyWord);
List<SysUserGridResponse> lists = extSysUserMapper.query(gridExample);
public List<SysUserGridResponse> query(UserGridRequest request) {
List<SysUserGridResponse> lists = extSysUserMapper.query(request);
lists.forEach(item -> {
List<SysUserRole> roles = item.getRoles();
List<Long> roleIds = roles.stream().filter(ObjectUtils::isNotEmpty).map(SysUserRole::getRoleId).collect(Collectors.toList());

View File

@ -0,0 +1,28 @@
export const buildParam = (conditions, keyword) => {
const result = {}
conditions.forEach(condition => {
const key = condition.field
const val = condition.value
const keyArray = key.split('.')
const len = keyArray.length
const fieldKey = keyArray[len - 1]
result[formatField(fieldKey)] = val
})
if (keyword === 0 || !!keyword) {
result['keyword'] = keyword
}
return result
}
const formatField = fieldText => {
const array = fieldText.split('_')
let result = ''
for (let index = 0; index < array.length; index++) {
let temp = array[index]
if (index) {
temp = temp.substr(0, 1).toLocaleUpperCase() + temp.substr(1)
}
result += temp
}
return result
}

View File

@ -322,9 +322,9 @@ export default {
},
formatCondition() {
const fildMap = {
'r.role_id': this.activeRole,
'd.dept_id': this.activeDept,
'u.enabled': this.activeStatus
'r.role_id_list': this.activeRole,
'd.dept_id_list': this.activeDept,
'u.enabled_list': this.activeStatus
}
const conditions = []
Object.keys(fildMap).forEach((ele) => {

View File

@ -126,8 +126,8 @@
@current-change="handleCurrentChange"
>
<el-table-column
prop="username"
key="username"
prop="username"
label="ID"
/>
<el-table-column
@ -139,8 +139,8 @@
/>
<!-- <el-table-column prop="gender" :label="$t('commons.gender')" width="60" /> -->
<el-table-column
prop="from"
key="from"
prop="from"
:label="$t('user.source')"
width="80"
>
@ -261,7 +261,10 @@
popper-class="reset-pwd"
trigger="click"
>
<svg-icon class="reset-pwd-icon" icon-class="icon_info_filled" />
<svg-icon
class="reset-pwd-icon"
icon-class="icon_info_filled"
/>
<div class="tips">{{ $t('user.recover_pwd') }}</div>
<div class="editer-form-title">
<span
@ -333,6 +336,7 @@ import { columnOptions } from './options'
import DeLayoutContent from '@/components/business/DeLayoutContent'
import { addOrder, formatOrders } from '@/utils/index'
import { pluginLoaded, defaultPwd } from '@/api/user'
import { buildParam } from '@/utils/GridConditionUtil'
import bus from '@/utils/bus'
import { Base64 } from 'js-base64'
/* import { ldapStatus, pluginLoaded } from '@/api/user' */
@ -568,17 +572,12 @@ export default {
})
},
search() {
const param = {
/* const param = {
orders: formatOrders(this.orderConditions),
conditions: [...this.cacheCondition]
}
if (this.nickName) {
param.conditions.push({
field: `concat(nick_name, ',' , email)`,
operator: 'like',
value: this.nickName
})
}
} */
const param = buildParam(this.cacheCondition, this.nickName)
const { currentPage, pageSize } = this.paginationConfig
userLists(currentPage, pageSize, param).then((response) => {
this.data = response.data.listObject

View File

@ -0,0 +1,16 @@
package io.dataease.plugins.common.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class KeywordRequest implements Serializable {
@ApiModelProperty("关键字")
private String keyword;
@ApiModelProperty("排序描述")
private List<String> orders;
}