forked from github/dataease
Merge pull request #5524 from dataease/pr@dev@perf_sqlinjection_whitelists
perf(sql白名单): sql注入检测白名单由外部配置文件覆盖
This commit is contained in:
commit
f896a0cc42
@ -1,18 +1,6 @@
|
|||||||
package io.dataease.commons.wrapper;
|
package io.dataease.commons.wrapper;
|
||||||
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import javax.servlet.ReadListener;
|
|
||||||
import javax.servlet.ServletInputStream;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletRequestWrapper;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import io.dataease.commons.holder.ThreadLocalContextHolder;
|
import io.dataease.commons.holder.ThreadLocalContextHolder;
|
||||||
import io.dataease.commons.utils.CommonBeanFactory;
|
import io.dataease.commons.utils.CommonBeanFactory;
|
||||||
@ -21,16 +9,30 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
|
|
||||||
|
import javax.servlet.ReadListener;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequestWrapper;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||||
|
|
||||||
private static Gson gson = new Gson();
|
private static Gson gson = new Gson();
|
||||||
|
|
||||||
|
private static final String defaultWhiteList = "/dataset/table/sqlPreview,/dataset/table/update,/dataset/field/multFieldValues,/dataset/field/linkMultFieldValues";
|
||||||
|
|
||||||
HttpServletRequest orgRequest = null;
|
HttpServletRequest orgRequest = null;
|
||||||
private Map<String, String[]> parameterMap;
|
private Map<String, String[]> parameterMap;
|
||||||
private final byte[] body; //用于保存读取body中数据
|
private final byte[] body; //用于保存读取body中数据
|
||||||
|
|
||||||
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) throws IOException{
|
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
|
||||||
super(request);
|
super(request);
|
||||||
orgRequest = request;
|
orgRequest = request;
|
||||||
parameterMap = request.getParameterMap();
|
parameterMap = request.getParameterMap();
|
||||||
@ -38,6 +40,7 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 重写几个HttpServletRequestWrapper中的方法
|
// 重写几个HttpServletRequestWrapper中的方法
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有参数名
|
* 获取所有参数名
|
||||||
*
|
*
|
||||||
@ -159,7 +162,6 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* 防止xss跨脚本攻击(替换,根据实际情况调整)
|
* 防止xss跨脚本攻击(替换,根据实际情况调整)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -208,9 +210,9 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkSqlInjection(Object obj){
|
public static boolean checkSqlInjection(Object obj) {
|
||||||
HttpServletRequest request = ServletUtils.request();
|
HttpServletRequest request = ServletUtils.request();
|
||||||
String url = request.getRequestURI().toString();
|
String url = request.getRequestURI();
|
||||||
|
|
||||||
if (null == obj) return false;
|
if (null == obj) return false;
|
||||||
if (StringUtils.isEmpty(obj.toString())) return false;
|
if (StringUtils.isEmpty(obj.toString())) return false;
|
||||||
@ -219,14 +221,14 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
|
|
||||||
if (StringUtils.isEmpty(orders)) return false;
|
if (StringUtils.isEmpty(orders)) return false;
|
||||||
|
|
||||||
String whiteLists = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.sqlinjection.whitelists", String.class, null);
|
String whiteLists = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.sqlinjection.whitelists", String.class, defaultWhiteList);
|
||||||
if (StringUtils.isNotEmpty(whiteLists)) {
|
if (StringUtils.isNotEmpty(whiteLists)) {
|
||||||
// 命中白名单 无需检测sql注入
|
// 命中白名单 无需检测sql注入
|
||||||
if (Arrays.stream(whiteLists.split(",")).anyMatch(item -> url.indexOf(item) != -1)) return false;
|
if (Arrays.stream(whiteLists.split(",")).anyMatch(item -> url.indexOf(item) != -1)) return false;
|
||||||
}
|
}
|
||||||
Pattern pattern= Pattern.compile("(.*\\=.*\\-\\-.*)|(.*(\\+).*)|(.*\\w+(%|\\$|#|&)\\w+.*)|(.*\\|\\|.*)|(.*\\s+(and|or)\\s+.*)" +
|
Pattern pattern = Pattern.compile("(.*\\=.*\\-\\-.*)|(.*(\\+).*)|(.*\\w+(%|\\$|#|&)\\w+.*)|(.*\\|\\|.*)|(.*\\s+(and|or)\\s+.*)" +
|
||||||
"|(.*\\b(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|sleep|extractvalue|updatexml|substring|database|concat|rand|gtid_subset)\\b.*)");
|
"|(.*\\b(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|sleep|extractvalue|updatexml|substring|database|concat|rand|gtid_subset)\\b.*)");
|
||||||
Matcher matcher=pattern.matcher(orders.toLowerCase());
|
Matcher matcher = pattern.matcher(orders.toLowerCase());
|
||||||
return matcher.find();
|
return matcher.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +238,7 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
boolean b = checkSqlInjection(value);
|
boolean b = checkSqlInjection(value);
|
||||||
if(b) {
|
if (b) {
|
||||||
ThreadLocalContextHolder.setData("包含SQL注入的参数,请检查参数!");
|
ThreadLocalContextHolder.setData("包含SQL注入的参数,请检查参数!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -320,7 +322,7 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if ((submitValues instanceof String[])) {
|
} else if ((submitValues instanceof String[])) {
|
||||||
for (String submitValue : (String[])submitValues){
|
for (String submitValue : (String[]) submitValues) {
|
||||||
if (checkXSSAndSql(submitValue)) {
|
if (checkXSSAndSql(submitValue)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -332,7 +334,7 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
|
|
||||||
private static String orders(String json) {
|
private static String orders(String json) {
|
||||||
if (StringUtils.isEmpty(json)) return null;
|
if (StringUtils.isEmpty(json)) return null;
|
||||||
try{
|
try {
|
||||||
Map<String, Object> map = new Gson().fromJson(json, Map.class);
|
Map<String, Object> map = new Gson().fromJson(json, Map.class);
|
||||||
Object orders = map.get("orders");
|
Object orders = map.get("orders");
|
||||||
|
|
||||||
@ -345,7 +347,7 @@ public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrappe
|
|||||||
return sort.toString();
|
return sort.toString();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ spring.cache.ehcache.config=classpath:/ehcache/ehcache.xml
|
|||||||
pagehelper.PageRowBounds=true
|
pagehelper.PageRowBounds=true
|
||||||
#excel\u7B49\u7528\u6237\u4E0A\u4F20\u6587\u4EF6\u8DEF\u5F84
|
#excel\u7B49\u7528\u6237\u4E0A\u4F20\u6587\u4EF6\u8DEF\u5F84
|
||||||
upload.file.path=/opt/dataease/data/kettle/
|
upload.file.path=/opt/dataease/data/kettle/
|
||||||
dataease.sqlinjection.whitelists=/dataset/table/sqlPreview,/dataset/table/update,/dataset/field/multFieldValues,/dataset/field/linkMultFieldValues
|
#dataease.sqlinjection.whitelists=/dataset/table/sqlPreview,/dataset/table/update,/dataset/field/multFieldValues,/dataset/field/linkMultFieldValues
|
||||||
#\u5F00\u542F\u538B\u7F29 \u63D0\u9AD8\u54CD\u5E94\u901F\u5EA6 \u51CF\u5C11\u5E26\u5BBD\u538B\u529B
|
#\u5F00\u542F\u538B\u7F29 \u63D0\u9AD8\u54CD\u5E94\u901F\u5EA6 \u51CF\u5C11\u5E26\u5BBD\u538B\u529B
|
||||||
server.compression.enabled=true
|
server.compression.enabled=true
|
||||||
server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
|
server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
|
||||||
|
Loading…
Reference in New Issue
Block a user