Commit 80b2cbf5 authored by litengwei's avatar litengwei

SQL Injection: MyBatis Mapper(SQL注入:MyBatis Mapper)

parent 9ca3358c
package com.yeejoin.amos.boot.module.common.api.interceptor;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Properties;
@Component
// 标志该类是一个拦截器
// {@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class PluginInterceptor implements Interceptor {
/**
* 进行拦截的时候要执行的方法
* @param invocation
* @return
* @throws Throwable
*/
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("====intercept======");
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
//由于逻辑关系,只会进入一次
if (args.length == 4) {
//4 个参数时
boundSql = mappedStatement.getBoundSql(parameter);
cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
} else {
//6 个参数时
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
//id为执行的mapper方法的全路径名,如com.metro.dao.UserMapper.insertUser
String id = mappedStatement.getId();
//获取到原始sql语句
String sql = boundSql.getSql();
if("com.yeejoin.amos.boot.module.common.api.mapper.OrgUsrMapper.selectPersonListCount".equals(id) ||
"com.yeejoin.amos.boot.module.common.api.mapper.OrgUsrMapper.selectPersonList".equals(id)) {
HashMap par = new HashMap();
if(parameter instanceof HashMap) {
par = (HashMap)((HashMap<?, ?>) parameter).get("map");
}
LinkedHashMap<String,String> fieldsValue = (LinkedHashMap<String, String>) par.get("fieldsValue");
Iterator<String> iterator = fieldsValue.keySet().stream().iterator();
while (iterator.hasNext()) {
String next = iterator.next();
sql = sql.replaceFirst("item",next).replaceFirst("ietmValue", new StringBuffer().append("'").append(fieldsValue.get(next)).append("'").toString());
}
//通过反射修改sql语句
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
field.set(boundSql, sql);
return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);
} else {
return invocation.proceed();
}
}
public Object plugin(Object target) {
System.out.println("-----------------------------plugin-------------------------");
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
System.out.println("====setProperties======");
}
}
\ No newline at end of file
...@@ -290,9 +290,15 @@ select * from ( ...@@ -290,9 +290,15 @@ select * from (
where cd.group_code =#{groupCode} and cds.instance_id is not null and where cd.group_code =#{groupCode} and cds.instance_id is not null and
cd.is_delete=0 cd.is_delete=0
group by cd.instance_id group by cd.instance_id
) result ) result
<if test="groupByName != null and groupByName!='' "> <if test="groupByName != null and groupByName!='' and groupByName=='result.carId'">
group by ${groupByName} group by result.carId
</if>
<if test="groupByName != null and groupByName!='' and groupByName=='result.fireFightingId'">
group by result.fireFightingId
</if>
<if test="groupByName != null and groupByName!='' and groupByName=='result.firstAidId'">
group by result.firstAidId
</if> </if>
</select> </select>
...@@ -334,8 +340,8 @@ select * from ( ...@@ -334,8 +340,8 @@ select * from (
cd.is_delete=0 cd.is_delete=0
group by cd.instance_id group by cd.instance_id
) result ) result
<if test="groupByName != null and groupByName!='' "> <if test="groupByName != null and groupByName!='' and groupByName=='result.deptId'">
group by ${groupByName} group by result.deptId
</if> </if>
</select> </select>
......
...@@ -110,10 +110,8 @@ ...@@ -110,10 +110,8 @@
<foreach collection="map.fieldsValue.keys" item="item"> <foreach collection="map.fieldsValue.keys" item="item">
<if test="item != 'bizOrgName'"> <if test="item != 'bizOrgName'">
AND a.${item} = #{map.fieldsValue[#{item}]} AND a.item = ietmValue
</if> </if>
</foreach> </foreach>
</if> </if>
</select> </select>
...@@ -218,7 +216,7 @@ ...@@ -218,7 +216,7 @@
<if test="map.fieldsValue != null"> <if test="map.fieldsValue != null">
<foreach collection="map.fieldsValue.keys" item="item"> <foreach collection="map.fieldsValue.keys" item="item">
<if test="item != 'bizOrgName'"> <if test="item != 'bizOrgName'">
AND a.${item} = #{map.fieldsValue[#{item}]} AND a.item = ietmValue
</if> </if>
</foreach> </foreach>
</if> </if>
...@@ -251,7 +249,7 @@ ...@@ -251,7 +249,7 @@
u.biz_org_code bizOrgCode, u.biz_org_code bizOrgCode,
<if test="fields != null"> <if test="fields != null">
<foreach collection="fields" item="item" separator=",">MAX(case f.field_code when #{item} then IFNULL(v.field_value_label, v.field_value) <foreach collection="fields" item="item" separator=",">MAX(case f.field_code when #{item} then IFNULL(v.field_value_label, v.field_value)
end) ${item} end) as #{item}
</foreach> </foreach>
</if> </if>
FROM FROM
......
package com.yeejoin.equipmanage.common.interceptor;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Properties;
@Component
// 标志该类是一个拦截器
// {@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class PluginInterceptor implements Interceptor {
/**
* 进行拦截的时候要执行的方法
* @param invocation
* @return
* @throws Throwable
*/
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("====intercept======");
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
//由于逻辑关系,只会进入一次
if (args.length == 4) {
//4 个参数时
boundSql = mappedStatement.getBoundSql(parameter);
cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
} else {
//6 个参数时
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
//id为执行的mapper方法的全路径名,如com.metro.dao.UserMapper.insertUser
String id = mappedStatement.getId();
//获取到原始sql语句
String sql = boundSql.getSql();
if("com.yeejoin.equipmanage.mapper.FormInstanceMapper.queryForMapList".equals(id)) {
//执行结果
HashMap<String,String> par = new LinkedHashMap<>();
if(parameter instanceof HashMap) {
par = (HashMap<String, String>)((HashMap<?, ?>) parameter).get("params");
}
Iterator<String> iterator = par.keySet().stream().iterator();
while (iterator.hasNext()) {
String next = iterator.next();
sql = sql.replace("item",next);
}
//通过反射修改sql语句
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
field.set(boundSql, sql);
return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);
} else {
return invocation.proceed();
}
}
public Object plugin(Object target) {
System.out.println("-----------------------------plugin-------------------------");
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
System.out.println("====setProperties======");
}
}
\ No newline at end of file
...@@ -17,15 +17,15 @@ import java.util.Map; ...@@ -17,15 +17,15 @@ import java.util.Map;
*/ */
public interface IFormInstanceService extends IService<FormInstance> { public interface IFormInstanceService extends IService<FormInstance> {
/** // /**
* 分页查询 // * 分页查询
* // *
* @param groupCode 分组编号 // * @param groupCode 分组编号
* @param current 当前页 // * @param current 当前页
* @param size 页面大小 // * @param size 页面大小
* @return Page // * @return Page
*/ // */
Page<Map<String, Object>> queryForInstancePage(String groupCode, long current, long size); // Page<Map<String, Object>> queryForInstancePage(String groupCode, long current, long size);
/** /**
* 创建 * 创建
......
...@@ -361,37 +361,37 @@ public class FormInstanceServiceImpl extends ServiceImpl<FormInstanceMapper, For ...@@ -361,37 +361,37 @@ public class FormInstanceServiceImpl extends ServiceImpl<FormInstanceMapper, For
return formInstanceMapper.getFormInstanceById(instanceId); return formInstanceMapper.getFormInstanceById(instanceId);
} }
@Override // @Override
public Page queryForInstancePage(String groupCode, long current, long size) { // public Page queryForInstancePage(String groupCode, long current, long size) {
List<FormGroupColumn> optionList = iFormGroupColumnService.queryByGroup(groupCode); // List<FormGroupColumn> optionList = iFormGroupColumnService.queryByGroup(groupCode);
Map<String, String[]> parameterMap = request.getParameterMap(); // Map<String, String[]> parameterMap = request.getParameterMap();
//说明:parameterMap 为静态map 不可修改,所以需要深拷贝 // //说明:parameterMap 为静态map 不可修改,所以需要深拷贝
Map<String, String[]> localMap = new HashMap<>(); // Map<String, String[]> localMap = new HashMap<>();
localMap.putAll(parameterMap); // localMap.putAll(parameterMap);
localMap.remove("current"); // localMap.remove("current");
localMap.remove("size"); // localMap.remove("size");
Map<String, String> params = new HashMap<>(); // Map<String, String> params = new HashMap<>();
if (!ValidationUtil.isEmpty(localMap)) { // if (!ValidationUtil.isEmpty(localMap)) {
for (String key : localMap.keySet()) { // for (String key : localMap.keySet()) {
if (!ValidationUtil.isEmpty(localMap.get(key))) { // if (!ValidationUtil.isEmpty(localMap.get(key))) {
params.put(key, localMap.get(key)[0]); // params.put(key, localMap.get(key)[0]);
} // }
} // }
} // }
Page page = new Page(); // Page page = new Page();
page.setCurrent(current); // page.setCurrent(current);
page.setSize(size); // page.setSize(size);
Map<String, Object> fieldNames = Bean.listToMap(optionList, "fieldName", "queryStrategy", FormGroupColumn.class); // Map<String, Object> fieldNames = Bean.listToMap(optionList, "fieldName", "queryStrategy", FormGroupColumn.class);
Page<Map<String, Object>> resultList = this.getBaseMapper().queryInstancePage(page, groupCode, fieldNames, params); // Page<Map<String, Object>> resultList = this.getBaseMapper().queryInstancePage(page, groupCode, fieldNames, params);
if (!ValidationUtil.isEmpty(resultList)) { // if (!ValidationUtil.isEmpty(resultList)) {
for (FormGroupColumn optionModel : optionList) { // for (FormGroupColumn optionModel : optionList) {
for (Map<String, Object> instanceMap : resultList.getRecords()) { // for (Map<String, Object> instanceMap : resultList.getRecords()) {
instanceMap.put(optionModel.getFieldName(), this.dataTypeProcess(optionModel.getFieldName(), instanceMap.get(optionModel.getFieldName()), optionModel.getDataType(), instanceMap)); // instanceMap.put(optionModel.getFieldName(), this.dataTypeProcess(optionModel.getFieldName(), instanceMap.get(optionModel.getFieldName()), optionModel.getDataType(), instanceMap));
} // }
} // }
} // }
return resultList; // return resultList;
} // }
@Override @Override
public List<Map<String, Object>> queryForMapList(String groupCode, Map<String, String> params) { public List<Map<String, Object>> queryForMapList(String groupCode, Map<String, String> params) {
......
package com.yeejoin.amos.knowledgebase.interceptor;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Properties;
@Component
// 标志该类是一个拦截器
// {@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class PluginInterceptor implements Interceptor {
/**
* 进行拦截的时候要执行的方法
* @param invocation
* @return
* @throws Throwable
*/
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("====intercept======");
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
//由于逻辑关系,只会进入一次
if (args.length == 4) {
//4 个参数时
boundSql = mappedStatement.getBoundSql(parameter);
cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);
} else {
//6 个参数时
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
//id为执行的mapper方法的全路径名,如com.metro.dao.UserMapper.insertUser
String id = mappedStatement.getId();
//获取到原始sql语句
String sql = boundSql.getSql();
if("com.yeejoin.amos.knowledgebase.face.orm.dao.DocContentMapper.queryDocBaseInfoList".equals(id)) {
//执行结果
HashMap<String,Object> par = new LinkedHashMap<>();
if(parameter instanceof HashMap) {
par = (HashMap<String, Object>)((HashMap<?, ?>) parameter).get("paramMap");
}
LinkedHashMap<String,String> fieldsValue = (LinkedHashMap<String, String>) par.get("extraFields");
Iterator<String> iterator = fieldsValue.keySet().stream().iterator();
LinkedHashMap<String,String> fieldsValue2 = (LinkedHashMap<String, String>) par.get("extraStrFilters");
Iterator<String> iterator1 = fieldsValue2.keySet().stream().iterator();
while (iterator.hasNext()) {
String next = iterator.next();
sql = sql.replaceFirst("_field",next);
}
while (iterator1.hasNext()) {
String next = iterator1.next();
sql = sql.replaceFirst("_str",next);
}
//通过反射修改sql语句
Field field = boundSql.getClass().getDeclaredField("sql");
field.setAccessible(true);
field.set(boundSql, sql);
return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);
} else {
return invocation.proceed();
}
}
public Object plugin(Object target) {
System.out.println("-----------------------------plugin-------------------------");
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
System.out.println("====setProperties======");
}
}
\ No newline at end of file
...@@ -6,38 +6,38 @@ ...@@ -6,38 +6,38 @@
<result column="fieldValue" property="fieldValue"/> <result column="fieldValue" property="fieldValue"/>
<result column="groupType" property="groupType"/> <result column="groupType" property="groupType"/>
</resultMap> </resultMap>
<select id="queryInstancePage" resultType="map"> <!-- <select id="queryInstancePage" resultType="map">-->
select <!-- select-->
d.* <!-- d.*-->
from <!-- from-->
( <!-- (-->
select <!-- select-->
i.INSTANCE_ID instanceId, <!-- i.INSTANCE_ID instanceId,-->
i.GROUP_CODE groupCode, <!-- i.GROUP_CODE groupCode,-->
<foreach collection="fieldNames" item="value" index="key" separator=","> <!-- <foreach collection="fieldNames" item="value" index="key" separator=",">-->
MAX(CASE WHEN i.FIELD_NAME = #{key} THEN i.FIELD_VALUE END) as #{key} <!-- MAX(CASE WHEN i.FIELD_NAME = #{key} THEN i.FIELD_VALUE END) as #{key}-->
</foreach> <!-- </foreach>-->
from <!-- from-->
wl_form_instance i <!-- wl_form_instance i-->
where i.GROUP_CODE = #{groupCode} <!-- where i.GROUP_CODE = #{groupCode}-->
GROUP by <!-- GROUP by-->
i.INSTANCE_ID)d <!-- i.INSTANCE_ID)d-->
<if test="params != null and params.size() > 0"> <!-- <if test="params != null and params.size() > 0">-->
where <!-- where-->
1=1 <!-- 1=1-->
<foreach collection="params" index="key" item="value" separator=""> <!-- <foreach collection="params" index="key" item="value" separator="">-->
<choose> <!-- <choose>-->
<when test="fieldNames[key] == 'like' and value !=null and value !=''"> <!-- <when test="fieldNames[key] == 'like' and value !=null and value !=''">-->
and d.${key} like concat('%',#{value},'%') <!-- and d.item like concat('%',#{value},'%')-->
</when> <!-- </when>-->
<when test="fieldNames[key] == 'eq' and value !=null and value !=''"> <!-- <when test="fieldNames[key] == 'eq' and value !=null and value !=''">-->
and d.${key} = #{value} <!-- and d.item = #{value}-->
</when> <!-- </when>-->
</choose> <!-- </choose>-->
</foreach> <!-- </foreach>-->
</if> <!-- </if>-->
order by instanceId desc <!-- order by instanceId desc-->
</select> <!-- </select>-->
<select id="getChildListdate" resultType="map"> <select id="getChildListdate" resultType="map">
SELECT getChildListdate ( #{id} ) ids SELECT getChildListdate ( #{id} ) ids
...@@ -80,10 +80,10 @@ ...@@ -80,10 +80,10 @@
<foreach collection="params" index="key" item="value" separator=""> <foreach collection="params" index="key" item="value" separator="">
<choose> <choose>
<when test="fieldNames[key] == 'like' and value !=null and value !=''"> <when test="fieldNames[key] == 'like' and value !=null and value !=''">
AND d.${key} like concat('%',#{value},'%') AND d.item like concat('%',#{value},'%')
</when> </when>
<when test="fieldNames[key] == 'eq' and value !=null and value !=''"> <when test="fieldNames[key] == 'eq' and value !=null and value !=''">
AND d.${key} = #{value} AND d.item = #{value}
</when> </when>
</choose> </choose>
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
(SELECT kdc.CATEGORY_NAME FROM knowledge_doc_category kdc WHERE kdc.SEQUENCE_NBR = DIRECTORY_ID) directoryName, (SELECT kdc.CATEGORY_NAME FROM knowledge_doc_category kdc WHERE kdc.SEQUENCE_NBR = DIRECTORY_ID) directoryName,
<if test="extraFields != null and extraFields.size > 0"> <if test="extraFields != null and extraFields.size > 0">
<foreach collection="extraFields" item="_field" > <foreach collection="extraFields" item="_field" >
${_field}, _field,
</foreach> </foreach>
</if> </if>
IFNULL(collectNum, 0) collectNum, IFNULL(quoteNum, 0) quoteNum, IFNULL(collect, "UNCOLLECT") collect IFNULL(collectNum, 0) collectNum, IFNULL(quoteNum, 0) quoteNum, IFNULL(collect, "UNCOLLECT") collect
...@@ -157,7 +157,7 @@ ...@@ -157,7 +157,7 @@
ORG_CODE LIKE CONCAT(#{permissionFilters.orgCode}, "%") ORG_CODE LIKE CONCAT(#{permissionFilters.orgCode}, "%")
AND AUDIT_STATUS IN AND AUDIT_STATUS IN
<foreach collection="permissionFilters.auditStatusList" item="auditStatus" open="(" close=")" separator=", "> <foreach collection="permissionFilters.auditStatusList" item="auditStatus" open="(" close=")" separator=", ">
${auditStatus} #{auditStatus}
</foreach> </foreach>
) )
</if> </if>
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
</if> </if>
<if test="extraStrFilters != null and extraStrFilters.size > 0"> <if test="extraStrFilters != null and extraStrFilters.size > 0">
<foreach collection="extraStrFilters" item="str"> <foreach collection="extraStrFilters" item="str">
AND ${str} AND _str
</foreach> </foreach>
</if> </if>
</where> </where>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment