SpringBoot过滤器过滤get及post请求中的XSS和SQL注入
- package com.wb.common;
- import java.io.BufferedReader;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Set;
- import java.util.Vector;
- import java.util.regex.Pattern;
- import javax.servlet.ReadListener;
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import org.springframework.util.StreamUtils;
- import com.sgcc.uap.utils.stream.StreamUtil;
- public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
- HttpServletRequest orgRequest = null;
- private Map<String, String[]> parameterMap;
- private final byte[] body; //用于保存读取body中数据
- public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) throws IOException{
- super(request);
- orgRequest = request;
- parameterMap = request.getParameterMap();
- body = StreamUtils.copyToByteArray(request.getInputStream());
- }
- // 重写几个HttpServletRequestWrapper中的方法
- /**
- * 获取所有参数名
- *
- * @return 返回所有参数名
- */
- @Override
- public Enumeration<String> getParameterNames() {
- Vector<String> vector = new Vector<String>(parameterMap.keySet());
- return vector.elements();
- }
- /**
- * 覆盖getParameter方法,将参数名和参数值都做xss & sql过滤。<br/>
- * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
- * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
- */
- @Override
- public String getParameter(String name) {
- String[] results = parameterMap.get(name);
- if (results == null || results.length <= 0)
- return null;
- else {
- String value = results[0];
- if (value != null) {
- value = xssEncode(value);
- }
- return value;
- }
- }
- /**
- * 获取指定参数名的所有值的数组,如:checkbox的所有数据 接收数组变量 ,如checkobx类型
- */
- @Override
- public String[] getParameterValues(String name) {
- String[] results = parameterMap.get(name);
- if (results == null || results.length <= 0)
- return null;
- else {
- int length = results.length;
- for (int i = 0; i < length; i++) {
- results[i] = xssEncode(results[i]);
- }
- return results;
- }
- }
- /**
- * 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br/>
- * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
- * getHeaderNames 也可能需要覆盖
- */
- @Override
- public String getHeader(String name) {
- String value = super.getHeader(xssEncode(name));
- if (value != null) {
- value = xssEncode(value);
- }
- return value;
- }
- /**
- * 将容易引起xss & sql漏洞的半角字符直接替换成全角字符
- *
- * @param s
- * @return
- */
- private static String xssEncode(String s) {
- if (s == null || s.isEmpty()) {
- return s;
- } else {
- s = stripXSSAndSql(s);
- }
- StringBuilder sb = new StringBuilder(s.length() + 16);
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- switch (c) {
- case '>':
- sb.append(">");// 转义大于号
- break;
- case '<':
- sb.append("<");// 转义小于号
- break;
- // case '\'':
- // sb.append("'");// 转义单引号
- // break;
- // case '\"':
- // sb.append(""");// 转义双引号
- // break;
- case '&':
- sb.append("&");// 转义&
- break;
- case '#':
- sb.append("#");// 转义#
- break;
- default:
- sb.append(c);
- break;
- }
- }
- return sb.toString();
- }
- /**
- * 获取最原始的request
- *
- * @return
- */
- public HttpServletRequest getOrgRequest() {
- return orgRequest;
- }
- /**
- * 获取最原始的request的静态方法
- *
- * @return
- */
- public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
- if (req instanceof XssAndSqlHttpServletRequestWrapper) {
- return ((XssAndSqlHttpServletRequestWrapper) req).getOrgRequest();
- }
- return req;
- }
- /**
- *
- * 防止xss跨脚本攻击(替换,根据实际情况调整)
- */
- public static String stripXSSAndSql(String value) {
- if (value != null) {
- // NOTE: It's highly recommended to use the ESAPI library and
- // uncomment the following line to
- // avoid encoded attacks.
- // value = ESAPI.encoder().canonicalize(value);
- // Avoid null characters
- /** value = value.replaceAll("", ""); ***/
- // Avoid anything between script tags
- Pattern scriptPattern = Pattern.compile(
- "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid anything in a
- // src="http://www.yihaomen.com/article/java/..." type of
- // e-xpression
- scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- value = scriptPattern.matcher(value).replaceAll("");
- // Remove any lonesome </script> tag
- scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
- value = scriptPattern.matcher(value).replaceAll("");
- // Remove any lonesome <script ...> tag
- scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid eval(...) expressions
- scriptPattern = Pattern.compile("eval\\((.*?)\\)",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid e-xpression(...) expressions
- scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid javascript:... expressions
- scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid vbscript:... expressions
- scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
- value = scriptPattern.matcher(value).replaceAll("");
- // Avoid onload= expressions
- scriptPattern = Pattern.compile("onload(.*?)=",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- value = scriptPattern.matcher(value).replaceAll("");
- }
- return value;
- }
- public static boolean checkXSSAndSql(String value) {
- boolean flag = false;
- if (value != null) {
- // NOTE: It's highly recommended to use the ESAPI library and
- // uncomment the following line to
- // avoid encoded attacks.
- // value = ESAPI.encoder().canonicalize(value);
- // Avoid null characters
- /** value = value.replaceAll("", ""); ***/
- // Avoid anything between script tags
- Pattern scriptPattern = Pattern.compile(
- "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid anything in a
- // src="http://www.yihaomen.com/article/java/..." type of
- // e-xpression
- scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Remove any lonesome </script> tag
- scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Remove any lonesome <script ...> tag
- scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid eval(...) expressions
- scriptPattern = Pattern.compile("eval\\((.*?)\\)",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid e-xpression(...) expressions
- scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid javascript:... expressions
- scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid vbscript:... expressions
- scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- // Avoid onload= expressions
- scriptPattern = Pattern.compile("onload(.*?)=",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
- flag = scriptPattern.matcher(value).find();
- if (flag) {
- return flag;
- }
- }
- return flag;
- }
- public final boolean checkParameter() {
- Map<String, String[]> submitParams = new HashMap(parameterMap);
- Set<String> submitNames = submitParams.keySet();
- for (String submitName : submitNames) {
- Object submitValues = submitParams.get(submitName);
- if ((submitValues instanceof String)) {
- if (checkXSSAndSql((String) submitValues)) {
- return true;
- }
- } else if ((submitValues instanceof String[])) {
- for (String submitValue : (String[])submitValues){
- if (checkXSSAndSql(submitValue)) {
- return true;
- }
- }
- }
- }
- return false;
- }
- @Override
- public BufferedReader getReader() throws IOException {
- return new BufferedReader(new InputStreamReader(getInputStream()));
- }
- @Override
- public ServletInputStream getInputStream() throws IOException {
- final ByteArrayInputStream bais = new ByteArrayInputStream(body);
- return new ServletInputStream() {
- @Override
- public int read() throws IOException {
- return bais.read();
- }
- @Override
- public boolean isFinished() {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean isReady() {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public void setReadListener(ReadListener arg0) {
- // TODO Auto-generated method stub
- }
- };
- }
- }
2.过滤器
- package com.wb.common;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.lang3.StringUtils;
- public class XssAndSqlFilter implements Filter {
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- throws IOException, ServletException {
- String method = "GET";
- String param = "";
- XssAndSqlHttpServletRequestWrapper xssRequest = null;
- if (request instanceof HttpServletRequest) {
- method = ((HttpServletRequest) request).getMethod();
- xssRequest = new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request);
- }
- if ("POST".equalsIgnoreCase(method)) {
- param = this.getBodyString(xssRequest.getReader());
- if(StringUtils.isNotBlank(param)){
- if(xssRequest.checkXSSAndSql(param)){
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.write(JSONResponseUtil.getWrappedERRString("您所访问的页面请求中有违反安全规则元素存在,拒绝访问!"));
- return;
- }
- }
- }
- if (xssRequest.checkParameter()) {
- response.setCharacterEncoding("UTF-8");
- response.setContentType("application/json;charset=UTF-8");
- PrintWriter out = response.getWriter();
- out.write(JSONResponseUtil.getWrappedERRString("您所访问的页面请求中有违反安全规则元素存在,拒绝访问!"));
- return;
- }
- chain.doFilter(xssRequest, response);
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- // TODO Auto-generated method stub
- }
- // 获取request请求body中参数
- public static String getBodyString(BufferedReader br) {
- String inputLine;
- String str = "";
- try {
- while ((inputLine = br.readLine()) != null) {
- str += inputLine;
- }
- br.close();
- } catch (IOException e) {
- System.out.println("IOException: " + e);
- }
- return str;
- }
- }
3.注册过滤器XssAndSqlFilter。
- **
- * Filter配置
- * @author 山河永慕
- */
- @Configuration
- public class FilterConfig {
- @Bean
- public FilterRegistrationBean xssFilterRegistration() {
- FilterRegistrationBean registration = new FilterRegistrationBean();
- registration.setDispatcherTypes(DispatcherType.REQUEST);
- registration.setFilter(new XssAndSqlFilter());
- registration.addUrlPatterns("/*");
- registration.setName("xssAndSqlFilter");
- registration.setOrder(Integer.MAX_VALUE);
- Map<String, String> initParameters = Maps.newHashMap();
- //-excludes用于配置不需要参数过滤的请求url;
- initParameters.put("excludes", "/favicon.ico,/img/*,/js/*,/css/*");
- //-isIncludeRichText默认为true,主要用于设置富文本内容是否需要过滤。
- initParameters.put("isIncludeRichText", "false");
- return registration;
- }
上面的有时候会拦截过于严谨
提供个个人版
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletRequestWrapper;
- import org.apache.commons.lang3.StringEscapeUtils;
- import org.apache.commons.lang3.StringUtils;
- /**
- * 防止XSS攻击
- */
- public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
- HttpServletRequest request;
- public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
- super(request);
- this.request = request;
- }
- @Override
- public String getParameter(String name) {
- String value = request.getParameter(name);
- System.out.println("name:" + name + "," + value);
- if (!StringUtils.isEmpty(value)) {
- // 转换Html
- value = StringEscapeUtils.escapeHtml4(value);
- }
- return value;
- }
- }
需要用到的jar包
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.4</version>
- </dependency>
附上参考链接
https://www.jianshu.com/p/bec4936d6672(比较完整版)
https://www.cnblogs.com/xiaowangbangzhu/p/10275580.html(模拟xss和分析版)
https://blog.csdn.net/yhhyhhyhhyhh/article/details/84504487(sql和cros最有效防止的)
SpringBoot过滤器过滤get及post请求中的XSS和SQL注入的更多相关文章
- DVWA中low级的sql注入漏洞的简单复现
第一次成功复现一个简单漏洞,于是写下这篇随笔记录一下 首先我们来看dvwa中low级的sql注入的源码 源码文件路径如下图: 源码如下: <?php if(isset($_GET['Submit ...
- mybatis的sql中使用$会出现sql注入示例
mybatis的sql中使用$会出现sql注入示例: 模拟简单登录场景: 页面代码: function login(){ //sql注入 var user = { username : "' ...
- PHP通用的XSS攻击过滤函数,Discuz系统中 防止XSS漏洞攻击,过滤HTML危险标签属性的PHP函数
XSS攻击在最近很是流行,往往在某段代码里一不小心就会被人放上XSS攻击的代码,看到国外有人写上了函数,咱也偷偷懒,悄悄的贴上来... 原文如下: The goal of this function ...
- PHP中该怎样防止SQL注入?
因为用户的输入可能是这样的: ? 1 value'); DROP TABLE table;-- 那么SQL查询将变成如下: ? 1 INSERT INTO `table` (`column`) VAL ...
- 什么是SQL注入以及mybatis中#{}为什么能防止SQL注入而${}为什么不能防止SQL注入
1.什么是SQL注入 答:SQL注入是通过把SQL命令插入到web表单提交或通过页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL指令. 注入攻击的本质是把用户输入的数据当做代码执行. 举例如: ...
- JDBC中的PreparedStatement-防止SQL注入攻击
在JDBC对数据库进行操作的时候,SQL注入是一种常见的针对数据库的注入攻击方式.如下面的代码所演示,在我们的提交字段中掺入了SQL语句,会使得程序的登录校验失效: package org.lyk.m ...
- 服务网关ZuulFilter过滤器--如何解决跨域请求中的OPTIONS请求
进行跨域请求的时候,并且请求头中有额外参数,比如token,客户端会先发送一个OPTIONS请求 来探测后续需要发起的跨域POST请求是否安全可接受 所以这个请求就不需要拦截,下面是处理方式 @Ove ...
- 防止xss和sql注入:JS特殊字符过滤正则
function stripscript(s) { var pattern = new RegExp("[%--`~!@#$^&*()=|{}':;',\\[\\].<> ...
- PHP用正则匹配字符串中的特殊字符防SQL注入
本文出至:新太潮流网络博客 /** * [用正则匹配字符串中的特殊字符] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http:/ ...
随机推荐
- Dijkstra算法求最短路径 Java实现
基本原理: 迪杰斯特拉算法是一种贪心算法. 首先建立一个集合,初始化只有一个顶点.每次将当前集合的所有顶点(初始只有一个顶点)看成一个整体,找到集合外与集合距离最近的顶点,将其加入集合并检查是否修改路 ...
- Oracle数据库主外键 级联删除记录
/** * 1. NO ACTION :指当删除主表中被引用列的数据时,如果子表的引用列中包含该值,则禁止该操作执行. * * 2. SET NULL :指当删除主表中被引用列的数据时,将子表中相应引 ...
- angular8 打包时 文件过大 导致内存溢出解决方案(记录)
在package.json 中添加 "scripts": { "ng": "ng", "start": "ng ...
- flask项目
虚拟环境需要 pipenv install flask pipenv install flask-sqlalchemy pipenv install python-dotenv pipenv inst ...
- 将java的jar包作为windows的服务来启动
1.在idea中用maven将程序打成jar,放到运行的目录中. 2.去github上面下载winsw: https://github.com/kohsuke/winsw/releases 3. 将W ...
- vue.js生成横向拓扑图
1.前端代码 <link href="https://magicbox.bk.tencent.com/static_api/v3/assets/bootstrap-3.3.4/css/ ...
- css 宽高等比
1.利用js 2.容器里添加图片,让图片的等比缩放撑大容器,图片z-index=负数,
- 使用Postman做接口测试
Postman是一个接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果, 从而验证响应中的结果数据是否和 ...
- MapReduce如何调优
Map阶段优化 1.在代码书写时优化,如尽量避免在map端创建变量等,因为map端是循环调用的,创建变量会增加内存的消耗,尽量将创建变量放到setup方法中 2.配置调优,可以在集群配置和任务运行时进 ...
- java 泛型 类型作为参量 Class<T> transform
Class<T> transform T:作为类型,用于定义变量: transform:作为具体类的类:用于创建实例. 类型信息是脱敏的具体类: 可以使用class的具体功能: 不能使用具 ...