springboot在Filter中过滤request的请求参数
什么是sql注入
是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)
通过Filter来过滤请求的参数
Filter:
import MyRequestWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @description: filter过滤器,默认拦截所有请求<BR/>
* @author: monster <BR/>
* @date: 2023/11/14 <BR/>
*/
@RequiredArgsConstructor
public class SqlFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request
, HttpServletResponse response
, FilterChain filterChain) throws ServletException, IOException {
// 请求重写
MyRequestWrapper requestWrapper = new MyRequestWrapper(request);
filterChain.doFilter(requestWrapper, response);
}
}
注入类:
import SqlFilter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
public class TemeiSqlConfiguration {
@Bean
public SqlFilter sqlFrameworkService() {
return new SqlFilter();
}
}
添加 resources/META-INF/spring
org.springframework.boot.autoconfigure.AutoConfiguration.imports
TemeiSqlConfiguration
过滤实现类
import org.apache.catalina.util.ParameterMap;
import org.apache.commons.codec.Charsets;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.Part;
import java.io.*;
import java.util.*;
/**
* <p> @Title MyRequestWrapper
* <p> @Description 过滤请求中的关键词
*
* @author monster
* @date 2023/11/14
*/
public class MyRequestWrapper extends HttpServletRequestWrapper {
private String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
//校验请求体并替换
body = checkSqlInject(stringBuilder.toString());
}
public static String dostring(String str) {
str = str.replaceAll(";", "");
str = str.replaceAll("&", "&");
str = str.replaceAll("<", "<");
str = str.replaceAll(">", ">");
str = str.replaceAll("'", "*");
str = str.replaceAll("--", "*");
// str=str.replaceAll("/","*");
str = str.replaceAll("%", "*");
str = str.replaceAll("select", "***");
str = str.replaceAll("update", "***");
str = str.replaceAll("delete", "***");
str = str.replaceAll("insert", "***");
str = str.replaceAll("trancate", "***");
str = str.replaceAll("char", "***");
return str;
}
/**
* 检查SQL注入
*
* @param value 参数值
* @throws IOException IO异常
*/
private String checkSqlInject(String value) {
if (null != value) {
return dostring(value);
}
return null;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
ServletInputStream servletInputStream = 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 byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream(), Charsets.UTF_8));
}
public String getBody() {
return this.body;
}
@Override
public String getParameter(String name) {
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return super.getParameterMap();
}
@Override
public Enumeration<String> getParameterNames() {
return super.getParameterNames();
}
@Override
public String[] getParameterValues(String name) {
//替换 路径参数
String[] s = new String[super.getParameterValues(name).length];
for (int i = 0; i < super.getParameterValues(name).length; i++) {
s[i] = checkSqlInject(super.getParameterValues(name)[i]);
}
return s;
}
}