1.创建XssAndSqlHttpServletRequestWrapper包装器,这是实现XSS过滤的关键,在其内重写了getParameter,getParameterValues,getHeader等方法,对http请求内的参数进行了过滤。
  1. package com.wb.common;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.ByteArrayInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.util.Enumeration;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. import java.util.Set;
  11. import java.util.Vector;
  12. import java.util.regex.Pattern;
  13.  
  14. import javax.servlet.ReadListener;
  15. import javax.servlet.ServletInputStream;
  16. import javax.servlet.http.HttpServletRequest;
  17. import javax.servlet.http.HttpServletRequestWrapper;
  18.  
  19. import org.springframework.util.StreamUtils;
  20.  
  21. import com.sgcc.uap.utils.stream.StreamUtil;
  22.  
  23. public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
  24.  
  25. HttpServletRequest orgRequest = null;
  26. private Map<String, String[]> parameterMap;
  27. private final byte[] body; //用于保存读取body中数据
  28.  
  29. public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) throws IOException{
  30. super(request);
  31. orgRequest = request;
  32. parameterMap = request.getParameterMap();
  33. body = StreamUtils.copyToByteArray(request.getInputStream());
  34. }
  35.  
  36. // 重写几个HttpServletRequestWrapper中的方法
  37. /**
  38. * 获取所有参数名
  39. *
  40. * @return 返回所有参数名
  41. */
  42. @Override
  43. public Enumeration<String> getParameterNames() {
  44. Vector<String> vector = new Vector<String>(parameterMap.keySet());
  45. return vector.elements();
  46. }
  47.  
  48. /**
  49. * 覆盖getParameter方法,将参数名和参数值都做xss & sql过滤。<br/>
  50. * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
  51. * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
  52. */
  53. @Override
  54. public String getParameter(String name) {
  55. String[] results = parameterMap.get(name);
  56. if (results == null || results.length <= 0)
  57. return null;
  58. else {
  59. String value = results[0];
  60. if (value != null) {
  61. value = xssEncode(value);
  62. }
  63. return value;
  64. }
  65. }
  66.  
  67. /**
  68. * 获取指定参数名的所有值的数组,如:checkbox的所有数据 接收数组变量 ,如checkobx类型
  69. */
  70. @Override
  71. public String[] getParameterValues(String name) {
  72. String[] results = parameterMap.get(name);
  73. if (results == null || results.length <= 0)
  74. return null;
  75. else {
  76. int length = results.length;
  77. for (int i = 0; i < length; i++) {
  78. results[i] = xssEncode(results[i]);
  79. }
  80. return results;
  81. }
  82. }
  83.  
  84. /**
  85. * 覆盖getHeader方法,将参数名和参数值都做xss & sql过滤。<br/>
  86. * 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
  87. * getHeaderNames 也可能需要覆盖
  88. */
  89. @Override
  90. public String getHeader(String name) {
  91.  
  92. String value = super.getHeader(xssEncode(name));
  93. if (value != null) {
  94. value = xssEncode(value);
  95. }
  96. return value;
  97. }
  98.  
  99. /**
  100. * 将容易引起xss & sql漏洞的半角字符直接替换成全角字符
  101. *
  102. * @param s
  103. * @return
  104. */
  105. private static String xssEncode(String s) {
  106. if (s == null || s.isEmpty()) {
  107. return s;
  108. } else {
  109. s = stripXSSAndSql(s);
  110. }
  111. StringBuilder sb = new StringBuilder(s.length() + 16);
  112. for (int i = 0; i < s.length(); i++) {
  113. char c = s.charAt(i);
  114. switch (c) {
  115. case '>':
  116. sb.append(">");// 转义大于号
  117. break;
  118. case '<':
  119. sb.append("<");// 转义小于号
  120. break;
  121. // case '\'':
  122. // sb.append("'");// 转义单引号
  123. // break;
  124. // case '\"':
  125. // sb.append(""");// 转义双引号
  126. // break;
  127. case '&':
  128. sb.append("&");// 转义&
  129. break;
  130. case '#':
  131. sb.append("#");// 转义#
  132. break;
  133. default:
  134. sb.append(c);
  135. break;
  136. }
  137. }
  138. return sb.toString();
  139. }
  140.  
  141. /**
  142. * 获取最原始的request
  143. *
  144. * @return
  145. */
  146. public HttpServletRequest getOrgRequest() {
  147. return orgRequest;
  148. }
  149.  
  150. /**
  151. * 获取最原始的request的静态方法
  152. *
  153. * @return
  154. */
  155. public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
  156. if (req instanceof XssAndSqlHttpServletRequestWrapper) {
  157. return ((XssAndSqlHttpServletRequestWrapper) req).getOrgRequest();
  158. }
  159.  
  160. return req;
  161. }
  162.  
  163. /**
  164. *
  165. * 防止xss跨脚本攻击(替换,根据实际情况调整)
  166. */
  167.  
  168. public static String stripXSSAndSql(String value) {
  169. if (value != null) {
  170. // NOTE: It's highly recommended to use the ESAPI library and
  171. // uncomment the following line to
  172. // avoid encoded attacks.
  173. // value = ESAPI.encoder().canonicalize(value);
  174. // Avoid null characters
  175. /** value = value.replaceAll("", ""); ***/
  176. // Avoid anything between script tags
  177. Pattern scriptPattern = Pattern.compile(
  178. "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
  179. value = scriptPattern.matcher(value).replaceAll("");
  180. // Avoid anything in a
  181. // src="http://www.yihaomen.com/article/java/..." type of
  182. // e-xpression
  183. scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
  184. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  185. value = scriptPattern.matcher(value).replaceAll("");
  186. // Remove any lonesome </script> tag
  187. scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
  188. value = scriptPattern.matcher(value).replaceAll("");
  189. // Remove any lonesome <script ...> tag
  190. scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
  191. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  192. value = scriptPattern.matcher(value).replaceAll("");
  193. // Avoid eval(...) expressions
  194. scriptPattern = Pattern.compile("eval\\((.*?)\\)",
  195. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  196. value = scriptPattern.matcher(value).replaceAll("");
  197. // Avoid e-xpression(...) expressions
  198. scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
  199. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  200. value = scriptPattern.matcher(value).replaceAll("");
  201. // Avoid javascript:... expressions
  202. scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
  203. value = scriptPattern.matcher(value).replaceAll("");
  204. // Avoid vbscript:... expressions
  205. scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
  206. value = scriptPattern.matcher(value).replaceAll("");
  207. // Avoid onload= expressions
  208. scriptPattern = Pattern.compile("onload(.*?)=",
  209. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  210. value = scriptPattern.matcher(value).replaceAll("");
  211. }
  212. return value;
  213. }
  214.  
  215. public static boolean checkXSSAndSql(String value) {
  216. boolean flag = false;
  217. if (value != null) {
  218. // NOTE: It's highly recommended to use the ESAPI library and
  219. // uncomment the following line to
  220. // avoid encoded attacks.
  221. // value = ESAPI.encoder().canonicalize(value);
  222. // Avoid null characters
  223. /** value = value.replaceAll("", ""); ***/
  224. // Avoid anything between script tags
  225. Pattern scriptPattern = Pattern.compile(
  226. "<[\r\n| | ]*script[\r\n| | ]*>(.*?)</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
  227. flag = scriptPattern.matcher(value).find();
  228. if (flag) {
  229. return flag;
  230. }
  231. // Avoid anything in a
  232. // src="http://www.yihaomen.com/article/java/..." type of
  233. // e-xpression
  234. scriptPattern = Pattern.compile("src[\r\n| | ]*=[\r\n| | ]*[\\\"|\\\'](.*?)[\\\"|\\\']",
  235. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  236. flag = scriptPattern.matcher(value).find();
  237. if (flag) {
  238. return flag;
  239. }
  240. // Remove any lonesome </script> tag
  241. scriptPattern = Pattern.compile("</[\r\n| | ]*script[\r\n| | ]*>", Pattern.CASE_INSENSITIVE);
  242. flag = scriptPattern.matcher(value).find();
  243. if (flag) {
  244. return flag;
  245. }
  246. // Remove any lonesome <script ...> tag
  247. scriptPattern = Pattern.compile("<[\r\n| | ]*script(.*?)>",
  248. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  249. flag = scriptPattern.matcher(value).find();
  250. if (flag) {
  251. return flag;
  252. }
  253. // Avoid eval(...) expressions
  254. scriptPattern = Pattern.compile("eval\\((.*?)\\)",
  255. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  256. flag = scriptPattern.matcher(value).find();
  257. if (flag) {
  258. return flag;
  259. }
  260. // Avoid e-xpression(...) expressions
  261. scriptPattern = Pattern.compile("e-xpression\\((.*?)\\)",
  262. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  263. flag = scriptPattern.matcher(value).find();
  264. if (flag) {
  265. return flag;
  266. }
  267. // Avoid javascript:... expressions
  268. scriptPattern = Pattern.compile("javascript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
  269. flag = scriptPattern.matcher(value).find();
  270. if (flag) {
  271. return flag;
  272. }
  273. // Avoid vbscript:... expressions
  274. scriptPattern = Pattern.compile("vbscript[\r\n| | ]*:[\r\n| | ]*", Pattern.CASE_INSENSITIVE);
  275. flag = scriptPattern.matcher(value).find();
  276. if (flag) {
  277. return flag;
  278. }
  279. // Avoid onload= expressions
  280. scriptPattern = Pattern.compile("onload(.*?)=",
  281. Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
  282. flag = scriptPattern.matcher(value).find();
  283. if (flag) {
  284. return flag;
  285. }
  286. }
  287. return flag;
  288. }
  289.  
  290. public final boolean checkParameter() {
  291. Map<String, String[]> submitParams = new HashMap(parameterMap);
  292. Set<String> submitNames = submitParams.keySet();
  293. for (String submitName : submitNames) {
  294. Object submitValues = submitParams.get(submitName);
  295. if ((submitValues instanceof String)) {
  296. if (checkXSSAndSql((String) submitValues)) {
  297. return true;
  298. }
  299. } else if ((submitValues instanceof String[])) {
  300. for (String submitValue : (String[])submitValues){
  301. if (checkXSSAndSql(submitValue)) {
  302. return true;
  303. }
  304. }
  305. }
  306. }
  307. return false;
  308. }
  309.  
  310. @Override
  311. public BufferedReader getReader() throws IOException {
  312. return new BufferedReader(new InputStreamReader(getInputStream()));
  313. }
  314.  
  315. @Override
  316. public ServletInputStream getInputStream() throws IOException {
  317. final ByteArrayInputStream bais = new ByteArrayInputStream(body);
  318. return new ServletInputStream() {
  319.  
  320. @Override
  321. public int read() throws IOException {
  322. return bais.read();
  323. }
  324.  
  325. @Override
  326. public boolean isFinished() {
  327. // TODO Auto-generated method stub
  328. return false;
  329. }
  330.  
  331. @Override
  332. public boolean isReady() {
  333. // TODO Auto-generated method stub
  334. return false;
  335. }
  336.  
  337. @Override
  338. public void setReadListener(ReadListener arg0) {
  339. // TODO Auto-generated method stub
  340.  
  341. }
  342. };
  343. }
  344.  
  345. }

2.过滤器

  1. package com.wb.common;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.PrintWriter;
  6.  
  7. import javax.servlet.Filter;
  8. import javax.servlet.FilterChain;
  9. import javax.servlet.FilterConfig;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.ServletRequest;
  12. import javax.servlet.ServletResponse;
  13. import javax.servlet.http.HttpServletRequest;
  14.  
  15. import org.apache.commons.lang3.StringUtils;
  16.  
  17. public class XssAndSqlFilter implements Filter {
  18.  
  19. @Override
  20. public void destroy() {
  21. // TODO Auto-generated method stub
  22.  
  23. }
  24.  
  25. @Override
  26. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  27. throws IOException, ServletException {
  28. String method = "GET";
  29. String param = "";
  30. XssAndSqlHttpServletRequestWrapper xssRequest = null;
  31. if (request instanceof HttpServletRequest) {
  32. method = ((HttpServletRequest) request).getMethod();
  33. xssRequest = new XssAndSqlHttpServletRequestWrapper((HttpServletRequest) request);
  34. }
  35. if ("POST".equalsIgnoreCase(method)) {
  36. param = this.getBodyString(xssRequest.getReader());
  37. if(StringUtils.isNotBlank(param)){
  38. if(xssRequest.checkXSSAndSql(param)){
  39. response.setCharacterEncoding("UTF-8");
  40. response.setContentType("application/json;charset=UTF-8");
  41. PrintWriter out = response.getWriter();
  42. out.write(JSONResponseUtil.getWrappedERRString("您所访问的页面请求中有违反安全规则元素存在,拒绝访问!"));
  43. return;
  44. }
  45. }
  46. }
  47. if (xssRequest.checkParameter()) {
  48. response.setCharacterEncoding("UTF-8");
  49. response.setContentType("application/json;charset=UTF-8");
  50. PrintWriter out = response.getWriter();
  51. out.write(JSONResponseUtil.getWrappedERRString("您所访问的页面请求中有违反安全规则元素存在,拒绝访问!"));
  52. return;
  53. }
  54. chain.doFilter(xssRequest, response);
  55. }
  56.  
  57. @Override
  58. public void init(FilterConfig arg0) throws ServletException {
  59. // TODO Auto-generated method stub
  60.  
  61. }
  62.  
  63. // 获取request请求body中参数
  64. public static String getBodyString(BufferedReader br) {
  65. String inputLine;
  66. String str = "";
  67. try {
  68. while ((inputLine = br.readLine()) != null) {
  69. str += inputLine;
  70. }
  71. br.close();
  72. } catch (IOException e) {
  73. System.out.println("IOException: " + e);
  74. }
  75. return str;
  76.  
  77. }
  78.  
  79. }

3.注册过滤器XssAndSqlFilter。

  1. **
  2. * Filter配置
  3. * @author 山河永慕
  4. */
  5. @Configuration
  6. public class FilterConfig {
  7.  
  8. @Bean
  9. public FilterRegistrationBean xssFilterRegistration() {
  10. FilterRegistrationBean registration = new FilterRegistrationBean();
  11. registration.setDispatcherTypes(DispatcherType.REQUEST);
  12. registration.setFilter(new XssAndSqlFilter());
  13. registration.addUrlPatterns("/*");
  14. registration.setName("xssAndSqlFilter");
  15. registration.setOrder(Integer.MAX_VALUE);
  16. Map<String, String> initParameters = Maps.newHashMap();
  17. //-excludes用于配置不需要参数过滤的请求url;
  18. initParameters.put("excludes", "/favicon.ico,/img/*,/js/*,/css/*");
  19. //-isIncludeRichText默认为true,主要用于设置富文本内容是否需要过滤。
  20. initParameters.put("isIncludeRichText", "false");
  21. return registration;
  22. }

上面的有时候会拦截过于严谨

提供个个人版

  1. import javax.servlet.http.HttpServletRequest;
  2. import javax.servlet.http.HttpServletRequestWrapper;
  3. import org.apache.commons.lang3.StringEscapeUtils;
  4. import org.apache.commons.lang3.StringUtils;
  5.  
  6. /**
  7. * 防止XSS攻击
  8. */
  9. public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
  10. HttpServletRequest request;
  11. public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
  12. super(request);
  13. this.request = request;
  14. }
  15. @Override
  16. public String getParameter(String name) {
  17. String value = request.getParameter(name);
  18. System.out.println("name:" + name + "," + value);
  19. if (!StringUtils.isEmpty(value)) {
  20. // 转换Html
  21. value = StringEscapeUtils.escapeHtml4(value);
  22. }
  23. return value;
  24. }
  25. }

需要用到的jar包

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-lang3</artifactId>
  4. <version>3.4</version>
  5. </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. Dijkstra算法求最短路径 Java实现

    基本原理: 迪杰斯特拉算法是一种贪心算法. 首先建立一个集合,初始化只有一个顶点.每次将当前集合的所有顶点(初始只有一个顶点)看成一个整体,找到集合外与集合距离最近的顶点,将其加入集合并检查是否修改路 ...

  2. Oracle数据库主外键 级联删除记录

    /** * 1. NO ACTION :指当删除主表中被引用列的数据时,如果子表的引用列中包含该值,则禁止该操作执行. * * 2. SET NULL :指当删除主表中被引用列的数据时,将子表中相应引 ...

  3. angular8 打包时 文件过大 导致内存溢出解决方案(记录)

    在package.json 中添加 "scripts": { "ng": "ng", "start": "ng ...

  4. flask项目

    虚拟环境需要 pipenv install flask pipenv install flask-sqlalchemy pipenv install python-dotenv pipenv inst ...

  5. 将java的jar包作为windows的服务来启动

    1.在idea中用maven将程序打成jar,放到运行的目录中. 2.去github上面下载winsw: https://github.com/kohsuke/winsw/releases 3. 将W ...

  6. vue.js生成横向拓扑图

    1.前端代码 <link href="https://magicbox.bk.tencent.com/static_api/v3/assets/bootstrap-3.3.4/css/ ...

  7. css 宽高等比

    1.利用js 2.容器里添加图片,让图片的等比缩放撑大容器,图片z-index=负数,

  8. 使用Postman做接口测试

    Postman是一个接口测试工具,在做接口测试的时候,Postman相当于一个客户端,它可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果, 从而验证响应中的结果数据是否和 ...

  9. MapReduce如何调优

    Map阶段优化 1.在代码书写时优化,如尽量避免在map端创建变量等,因为map端是循环调用的,创建变量会增加内存的消耗,尽量将创建变量放到setup方法中 2.配置调优,可以在集群配置和任务运行时进 ...

  10. java 泛型 类型作为参量 Class<T> transform

    Class<T> transform T:作为类型,用于定义变量: transform:作为具体类的类:用于创建实例. 类型信息是脱敏的具体类: 可以使用class的具体功能: 不能使用具 ...