SpringBoot中Post请求参数过滤SQL防止注入
BodyReaderRequestWrapper 代码:
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
public class BodyReaderRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public String getBody() {
return body;
}
/**
* 取出请求体body中的参数(创建对象时执行)
* @param request
*/
public BodyReaderRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder sb = new StringBuilder();
InputStream ins = request.getInputStream();
BufferedReader isr = null;
try{
if (ins != null) {
isr = new BufferedReader(new InputStreamReader(ins));
char[] charBuffer = new char[128];
int readCount;
while ((readCount = isr.read(charBuffer)) != -1) {
sb.append(charBuffer, 0, readCount);
}
}
} finally {
if(isr != null) {
isr.close();
}
}
sb.toString();
body = sb.toString();
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes());
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayIns.read();
}
};
}
}
SqlFilter 代码:
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
@WebFilter(urlPatterns = "/*")
public class SqlFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String contentType = request.getContentType();
BodyReaderRequestWrapper wrapper = null;
if ("application/json".equals(contentType)) {
wrapper = new BodyReaderRequestWrapper(request);
String requestPostStr = wrapper.getBody();
if (requestPostStr.startsWith("{")) {
//解析json对象
boolean b = resolveJSONObjectObj(requestPostStr);
if (!b) return;
} else if (requestPostStr.startsWith("[")) {
//把数据转换成json数组
JSONArray jsonArray = JSONArray.parseArray(requestPostStr);
jsonArray.forEach(json -> {
//解析json对象
boolean b = resolveJSONObjectObj(json.toString());
if (!b) return;
});
}
} else {
//application/x-www-form-urlencoded
Map<String, String[]> parameterMap = request.getParameterMap();
for (Map.Entry<String,String[]> entry : parameterMap.entrySet()) {
//校验参数值是否合法
String[] value = entry.getValue();
for (String s : value) {
//校验参数值是否合法
boolean b = verifySql(s);
if (!b) {
return;
}
}
}
}
if (wrapper == null) {
filterChain.doFilter(servletRequest,servletResponse);
} else {
filterChain.doFilter(wrapper,servletResponse);
}
}
/**
* 对JSONObject对象进行递归参数解析
* @param requestPostStr
* @return
*/
private boolean resolveJSONObjectObj(String requestPostStr) {
boolean isover = true;
// 创建需要处理的json对象
JSONObject jsonObject = JSONObject.parseObject(requestPostStr);
// 获取所有的参数key
Set<String> keys = jsonObject.keySet();
if (keys.size() > 0) {
for (String key : keys) {
//获取参数名称
String value;
if (jsonObject.get(key) != null) {
value = String.valueOf(jsonObject.get(key));
//当value为数组时
if(value.startsWith("[")){
//把数据转换成json数组
JSONArray jsonArray = JSONArray.parseArray(value);
for (Object o : jsonArray) {
//解析json对象
boolean b = resolveJSONObjectObj(o.toString());
if (!b) {
isover = false;
break;
}
}
} else if (value.startsWith("{")) {
boolean b = resolveJSONObjectObj(value);
if (!b) {
isover = false;
break;
}
} else {
//校验参数值是否合法
boolean b = verifySql(value);
if (!b) {
isover = false;
break;
}
}
}
}
}
return isover;
}
@Override
public void destroy() {
}
/**
* 校验参数非法字符
*/
public boolean verifySql(String parameter) {
if (
parameter.toLowerCase().contains("select")
|| parameter.toLowerCase().contains("update")
|| parameter.toLowerCase().contains("delete")
|| parameter.toLowerCase().contains("insert")
|| parameter.toLowerCase().contains("truncate")
|| parameter.toLowerCase().contains("substr")
|| parameter.toLowerCase().contains("char")
|| parameter.toLowerCase().contains("exec")
|| parameter.toLowerCase().contains("master")
|| parameter.toLowerCase().contains("drop")
|| parameter.toLowerCase().contains("execute")
|| parameter.toLowerCase().contains("xp_cmdshell")
|| parameter.toLowerCase().contains("use")
|| parameter.toLowerCase().contains("column_name")
|| parameter.toLowerCase().contains("information_schema.columns")
|| parameter.toLowerCase().contains("table_schema")
|| parameter.toLowerCase().contains("union")
) {
return false;
} else {
return true;
}
}
}