Springboot过滤xss

两种xss类型:存储型xss、反射型xss。

简介:

存储型:持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie等

反射型:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。

问题产生:

公司代码发布前需要进行3部分安全扫描,其中第一个就出现这种问题了。如图。

解决方法:

首先springboot后台常见的接收参数一般有三种方式:@RequestParam 、 @PathVariable 、 @RequestBody(1).过滤表单传值(?传参 即  @RequestParam)

step1:创建包装request的类 XssHttpServletRequestWrapper

package com.cpic.config.xss;import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringEscapeUtils;import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;//参考:https://www.freesion.com/article/7503775029/
//过滤表单传值(?传参 即  @RequestParam)
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {public XssHttpServletRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String getQueryString() {System.out.println("11===");return StringEscapeUtils.escapeHtml4(super.getQueryString());}@Overridepublic String getParameter(String name) {System.out.println("22===");return StringEscapeUtils.escapeHtml4(super.getParameter(name));}@Overridepublic String[] getParameterValues(String name) {//过滤表单传值(?传参 即  @RequestParam)System.out.println("33===");String[] values = super.getParameterValues(name);if (ArrayUtils.isEmpty(values)) {return values;}int length = values.length;String[] escapeValues = new String[length];for (int i = 0; i < length; i++) {escapeValues[i] = StringEscapeUtils.escapeHtml4(values[i]);}return escapeValues;}//-------------------补充(考虑到部分参数会在header里面传过来)------------------//参考:https://blog.csdn.net/weixin_38497019/article/details/95940285@Overridepublic String getHeader(String name) {String value = super.getHeader(name);if (value == null)return null;return StringEscapeUtils.escapeHtml4(value);}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream bais = new ByteArrayInputStream(inputHandlers(super.getInputStream ()).getBytes ());return new ServletInputStream() {@Overridepublic int read() throws IOException {return bais.read();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) { }};}public   String inputHandlers(ServletInputStream servletInputStream){StringBuilder sb = new StringBuilder();BufferedReader reader = null;try {reader = new BufferedReader(new InputStreamReader(servletInputStream, Charset.forName("UTF-8")));String line = "";while ((line = reader.readLine()) != null) {sb.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (servletInputStream != null) {try {servletInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}return  StringEscapeUtils.escapeHtml4(sb.toString ());}//如果不喜欢 使用StringEscapeUtils.escapeHtml4 的方法可以采取类似下面自定义的方法
/*    private static String cleanXSS(String value) {value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");value = value.replaceAll("%3C", "&lt;").replaceAll("%3E", "&gt;");value = value.replaceAll("\\(", "(").replaceAll("\\)", ")");value = value.replaceAll("%28", "(").replaceAll("%29", ")");value = value.replaceAll("'", "'");value = value.replaceAll("eval\\((.*)\\)", "");value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");value = value.replaceAll("script", "");return value;}*/}

step2:创建自定义过滤器XssFilter过滤请求

package com.cpic.config.xss;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;//参考:https://www.freesion.com/article/7503775029/
//过滤表单传值(?传参 即  @RequestParam)
@WebFilter(filterName="XSSFilter", urlPatterns="/*")
public class XssFilter implements Filter {FilterConfig filterConfig = null;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("过滤器初始化");this.filterConfig = filterConfig;}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("执行过滤操作");filterChain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) servletRequest), servletResponse);}@Overridepublic void destroy() {System.out.println("过滤器销毁");this.filterConfig = null;}}

step3:在springboot启动类添加过滤器扫描(@ServletComponentScan("com.cpic.config.xss")这个就是上面自定义过滤器的位置)

@EnableScheduling
@EnableAsync
@SpringBootApplication(exclude={RedisAutoConfiguration.class,RedisRepositoriesAutoConfiguration.class})
@ServletComponentScan("com.cpic.config.xss")
//过滤表单传值(?传参 即  @RequestParam)
public class Application extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication springApplication = new SpringApplication(Application.class);springApplication.setBannerMode(Mode.OFF);springApplication.run(args);}protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(Application.class);}}
(2).过滤类似 @GetMapping("/testXss/{openId}")(url 后面/传参 即  @PathVariable)

step:创建类 XssHandlerMappingPostProcessor

package com.cpic.config.xss;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.util.HtmlUtils;
import org.springframework.web.util.UrlPathHelper;import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;//https://blog.csdn.net/whatzhang007/article/details/111589693
//http://www.chaiguanxin.com/articles/2020/03/18/1584495603475.html
//过滤url后面的/传值(/传参 即  @PathVariable)
@Component
public class XssHandlerMappingPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException{return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException{if(bean instanceof AbstractHandlerMapping){AbstractHandlerMapping ahm = (AbstractHandlerMapping) bean;ahm.setUrlPathHelper(new XssUrlPathHelper());}return bean;}static class XssUrlPathHelper extends UrlPathHelper {@Overridepublic Map<String, String> decodePathVariables(HttpServletRequest request, Map<String, String> vars){Map<String, String> result = super.decodePathVariables(request, vars);if(!CollectionUtils.isEmpty(result)){for(String key : result.keySet()){result.put(key, cleanXSS(result.get(key)));}}return result;}@Overridepublic MultiValueMap<String, String> decodeMatrixVariables(HttpServletRequest request,MultiValueMap<String, String> vars){MultiValueMap<String, String> mvm = super.decodeMatrixVariables(request, vars);if(!CollectionUtils.isEmpty(mvm)){for(String key : mvm.keySet()){List<String> value = mvm.get(key);for(int i = 0; i < value.size(); i++){value.set(i, cleanXSS(value.get(i)));}}}return mvm;}private String cleanXSS(String value){return HtmlUtils.htmlEscape(value);}}}
(3).过滤json传值(json传参 即  @RequestBody)

step:创建类WebConfig

package com.cpic.config.webmvc;import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.io.IOException;//https://www.freesion.com/article/7503775029/
//过滤post请求json传值(@RequestBody)
@Configuration
public class WebConfig implements WebMvcConfigurer, InitializingBean {/*** 默认就是@Autowired(required=true),表示注入的时候,该bean必须存在,否则就会注入失败required = false,表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错*/@Autowired(required = false)private ObjectMapper objectMapper;private SimpleModule getSimpleModule() {SimpleModule simpleModule = new SimpleModule();simpleModule.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class));return simpleModule;}/*** 初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法* 这个方法将在所有的属性被初始化后调用,但是会在init前调用* @throws Exception*/@Overridepublic void afterPropertiesSet() throws Exception {if (objectMapper != null) {SimpleModule simpleModule = getSimpleModule();objectMapper.registerModule(simpleModule);}}
}/*** 对入参的json进行转义*/
class JsonHtmlXssDeserializer extends JsonDeserializer<String> {public JsonHtmlXssDeserializer(Class<String> string) {super();}@Overridepublic Class<String> handledType() {return String.class;}@Overridepublic String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {String value = jsonParser.getValueAsString();if (value != null) {return StringEscapeUtils.escapeHtml4(value.toString());}return value;}
}
(4).过滤?和/传值(即  @RequestParam和@PathVariable)

由于?和/实际上都是字符串接收参数,可以定义一个字符串转换器,让后配置到mvcConfig

step1:创建类EscapeStringConverter

package com.cpic.config.xss;import org.apache.commons.lang3.StringUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import org.springframework.web.util.HtmlUtils;//http://www.10qianwan.com/articledetail/766291.html
@Component
public class EscapeStringConverter implements Converter<String, String> {@Overridepublic String convert(String s) {
//同理可以和上面的一样自定义过滤转换规则return StringUtils.isEmpty(s) ? s : HtmlUtils.htmlEscape(s);}}

step2:WebMvcConfig中添加如下方法

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(new TokenDataHandlerMethodArgumentResolver());
}

测试

a).测试方法

//测试  @RequestBody 传参过滤(json传参)
@PostMapping("/testXss")
public BaseResponseResult test(@RequestBody User user){System.out.println(user.getUserCode());return new BaseResponseResult(200,"testXss",user.getUserCode());
}//测试  @PathVariable 传参过滤(url后面带参数传参)
@GetMapping("/testXss/{openId}")
public BaseResponseResult getBasicUserInfo(@PathVariable(value="openId",required=true) String openId){System.out.println(openId);return new BaseResponseResult(200,"testXss",openId);
}//测试  @RequestParam 传参过滤(?传参)
@GetMapping("/testXss1")
public BaseResponseResult test(@RequestParam(value="openId",required=true) String openId){System.out.println(openId);return new BaseResponseResult(200,"testXss",openId);
}

b).测试结果

补充:

a).sql注入常用语句:(参考:https://blog.csdn.net/u012610902/article/details/80994242)

<script>alert('hello,gaga!');</script> //经典语句,哈哈!

>"'><img src="javascript.:alert('XSS')">

>"'><script>alert('XSS')</script>

<table background='javascript.:alert(([code])'></table>

<object type=text/html data='javascript.:alert(([code]);'></object>

"+alert('XSS')+"

'><script>alert(document.cookie)</script>

='><script>alert(document.cookie)</script>

<script>alert(document.cookie)</script>

<script>alert(vulnerable)</script>

<script>alert('XSS')</script>

<img src="javascript:alert('XSS')">

b).过滤器白名单(富文本样式等)

参考(https://www.cnblogs.com/uzxin/p/13476100.html)

Springboot过滤xss相关推荐

  1. java 过滤脚本_【快学SpringBoot】过滤XSS脚本攻击(包括json格式)

    XSS攻击是什么 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安 ...

  2. Java添加过滤器过滤xss入侵

    Filter过滤器过滤XSS攻击 一.springmvc框架 1.添加自定义过滤器文件XssFilter.java和XssHttpServletRequestWrapper.java XssFilte ...

  3. XSS是什么?如何防御?手摸手教你Springboot配置XSS防御,深入代码解析!

    XSS防御 一.简单了解一下XSS 二.如何防御 SpringBoot配置XSS防御 代码解析 一.简单了解一下XSS 来,百度先抄一段. HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别 ...

  4. springboot增加XSS跨站脚本攻击防护功能

    参考 文章https://my.oschina.net/u/4407261/blog/3395458 XSS原理 xss攻击的原理是利用前后端校验不严格,用户将攻击代码植入到数据中提交到了后台,当这些 ...

  5. java 过滤xss脚本_Java Web应用程序的反跨站点脚本(XSS)过滤器

    java 过滤xss脚本 这是为Java Web应用程序编写的一个好简单的反跨站点脚本(XSS)过滤器. 它的基本作用是从请求参数中删除所有可疑字符串,然后将其返回给应用程序. 这是我以前关于该主题的 ...

  6. htmlspecialchars() 函数过滤XSS的问题

    htmlspecialchars()函数的功能如下: htmlspecialchars() 函数把预定义的字符转换为 HTML 实体. 预定义的字符是: & (和号)成为 & &quo ...

  7. Springboot 对应XSS漏洞类配置处理

    前言:SpringBoot防Xss攻击,这几天自己学习了一下SpringBoot项目怎么预防Xss攻击,这里记录一下怎么防止Xss攻击的代码,等以后有需要用到的话,自己可以快速找到 1. 什么是 XS ...

  8. SpringBoot2.0系列教程(十三)Springboot防止XSS攻击

    Hello大家好,本章我们添加防止XSS攻击功能 .有问题可以加我VX:Mrchuchen. 一:什么是XSS XSS攻击全称跨站脚本攻击,是一种在web应用中的计算机安全漏洞,它允许恶意web用户将 ...

  9. springboot防止XSS攻击和sql注入

    文章目录 1. XSS跨站脚本攻击 ①:XSS漏洞介绍 ②:XSS漏洞分类 ③:防护建议 2. SQL注入攻击 ①:SQL注入漏洞介绍 ②:防护建议 3. SpringBoot中如何防止XSS攻击和s ...

最新文章

  1. swift 3.0 json解析、字典转模型三种方案
  2. uart口图片_认识UART接口
  3. JS 删除 cookie
  4. 一个简单的内存分配例子
  5. [Oracle]UNIX与Windows 2000上Oracle的差异(I)
  6. word打开文档很久很慢_word打开慢,教您怎么解决word打开慢
  7. 谷歌被墙,如何给谷歌浏览器添加迅雷下载插件
  8. 客户端DDK编译环境配置说明
  9. WIN10系统——打开PB的帮助文档
  10. 测试驱动开发(TDD)开发思路
  11. 10 - 箱梁网格划分
  12. 三菱伺服驱动器说明书_干货——PLC控制伺服系统(伺服电机)
  13. 机载激光雷达原理与应用科普(二)
  14. PCIE原理-002:PCIE地址是如何映射的
  15. java初学者学习路线
  16. php比较asc,php小技巧之过滤ascii控制字符
  17. LibreOJ - 10015 扩散
  18. 求线段或直线与圆的交点
  19. 【Statistics】HYPOTHESIS TEST(SIGNIFICANCE TEST)
  20. 特征空间、(数据集)线性可分:线性(二分类)模型

热门文章

  1. html中用js格式化JSON输出
  2. 在VS Code中开发ESP32遇到如下IDF_PATH环境变量不一致的警告问题
  3. 判断数组相同数c语言_单片机常用的14个C语言算法,看过的都成了大神!
  4. shader学习摘要(八)unity光源类型
  5. html ios 视频播放不了,html中的video标签在ios微信中无法播放的解决方法之一
  6. 读《终身学习》 哈佛毕业后的六堂课,整理总结
  7. python_给视频打马赛克
  8. 计算机通识必修课程学什么内容,计算机公共必修课《大学计算机基础》课程教学大纲...
  9. 提升企业团队凝聚力的四步法
  10. 申请加精—ERP实施方法论的比较(SAP、 Oracle、J.D.E、BANN、用友等实施方法论)...