1.创建XssAndSqlHttpServletRequestWrapper包装器,这是实现XSS过滤的关键,在其内重写了getParameter,getParameterValues,getHeader等方法,对http请求内的参数进行了过滤。
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注入的更多相关文章

  1. DVWA中low级的sql注入漏洞的简单复现

    第一次成功复现一个简单漏洞,于是写下这篇随笔记录一下 首先我们来看dvwa中low级的sql注入的源码 源码文件路径如下图: 源码如下: <?php if(isset($_GET['Submit ...

  2. mybatis的sql中使用$会出现sql注入示例

    mybatis的sql中使用$会出现sql注入示例: 模拟简单登录场景: 页面代码: function login(){ //sql注入 var user = { username : "' ...

  3. PHP通用的XSS攻击过滤函数,Discuz系统中 防止XSS漏洞攻击,过滤HTML危险标签属性的PHP函数

    XSS攻击在最近很是流行,往往在某段代码里一不小心就会被人放上XSS攻击的代码,看到国外有人写上了函数,咱也偷偷懒,悄悄的贴上来... 原文如下: The goal of this function ...

  4. PHP中该怎样防止SQL注入?

    因为用户的输入可能是这样的: ? 1 value'); DROP TABLE table;-- 那么SQL查询将变成如下: ? 1 INSERT INTO `table` (`column`) VAL ...

  5. 什么是SQL注入以及mybatis中#{}为什么能防止SQL注入而${}为什么不能防止SQL注入

    1.什么是SQL注入 答:SQL注入是通过把SQL命令插入到web表单提交或通过页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL指令. 注入攻击的本质是把用户输入的数据当做代码执行. 举例如: ...

  6. JDBC中的PreparedStatement-防止SQL注入攻击

    在JDBC对数据库进行操作的时候,SQL注入是一种常见的针对数据库的注入攻击方式.如下面的代码所演示,在我们的提交字段中掺入了SQL语句,会使得程序的登录校验失效: package org.lyk.m ...

  7. 服务网关ZuulFilter过滤器--如何解决跨域请求中的OPTIONS请求

    进行跨域请求的时候,并且请求头中有额外参数,比如token,客户端会先发送一个OPTIONS请求 来探测后续需要发起的跨域POST请求是否安全可接受 所以这个请求就不需要拦截,下面是处理方式 @Ove ...

  8. 防止xss和sql注入:JS特殊字符过滤正则

    function stripscript(s) { var pattern = new RegExp("[%--`~!@#$^&*()=|{}':;',\\[\\].<> ...

  9. PHP用正则匹配字符串中的特殊字符防SQL注入

    本文出至:新太潮流网络博客 /** * [用正则匹配字符串中的特殊字符] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http:/ ...

随机推荐

  1. Golang Web应用 创建docker镜像笔记(win 平台)

    记录的是 本地编译好了再创建容器镜像的方法 ,这样子生成的镜像文件比较小,方便分发部署 win 平台需要设置golang交叉编译 生成linux可执行文件 CMD下: Set GOOS="l ...

  2. Python学习日记(三十六) Mysql数据库篇 四

    MySQL作业分析 五张表的增删改查: 完成所有表的关系创建 创建教师表(tid为这张表教师ID,tname为这张表教师的姓名) create table teacherTable( tid int ...

  3. ubuntu17升级到18.04

    问题描述: ubuntu不是LTS长期支持的版本在支持期过了,没有apt源提供支持.所以需要升级到对应的LTS版本 问题解决: 实验环境: ubuntu17.10--->ubuntu18.04. ...

  4. Vim 中进行文件目录操作

    Vim 中进行文件目录操作 当前文件名 我们知道Vim有48个寄存器,其中%只读寄存器中保存着当前文件路径. 例如在/home/harttle/下打开src/main.cpp,我们打印%的值: :ec ...

  5. golang reflect知识集锦

    目录 反射之结构体tag Types vs Kinds reflect.Type vs reflect.Value 2019/4/20 补充 reflect.Value转原始类型 获取类型底层类型 遍 ...

  6. 使用Matplotlab画图

    1.绘制折线图 #! /usr/bin/env python#encoding=utf-8 # 用于python2import sys reload(sys) sys.setdefaultencodi ...

  7. Android中使用ps命令查看进程PID

    adb shell "ps | grep com.sina.weibo" 这个命令可以看到微博的应用线程信息. PID:进程号 PPID:父进程号 VSIZE:进程的虚拟内存大小 ...

  8. C语言const和volatile关键字

    这部分内容比较简单,我这里直接先做总结,然后通过写三个测试代码,体会其中的关键点 一.总结      1.const使得变量具有只读属性(但是不一定就是不能更改) 2.const不能定义真正意义上的常 ...

  9. js动画---多物体运动

    对于多物体运动和单个物体运动来说,没有特别大的区别,实现原理基本上是一样的,都是通过定时器来实现的,但是多物体有一些地方需要注意,具体哪些需要注意,我将在下面的程序中说明. 首先,我们需要建立几个li ...

  10. 项目Beta冲刺(团队)——05.24(2/7)

    项目Beta冲刺(团队)--05.24(2/7) 格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺(团队) 团队名称:为了交项目干杯 作业目标:记录Beta敏捷冲刺第2 ...