spring boot / cloud (一) 使用filter防止XSS

前言

XSS(跨站脚本攻击)

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

思路

基于filter拦截,将特殊字符替换为html转意字符 (如: "<" 转意为 "&lt;") , 需要拦截的点如下:

  • 请求头 requestHeader

  • 请求体 requestBody

  • 请求参数 requestParameter

实现

1.创建XssHttpServletRequestWrapper类

在获取请求头,请求参数的这些地方,将目标值使用HtmlUtils.htmlEscape方法转意为html字符,而避免恶意代码参与到后续的流程中


/**
* XssHttpServletRequestWrapper.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package org.itkk.udf.core.xss; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import org.springframework.web.util.HtmlUtils; /**
* 描述 : 跨站请求防范
*
* @author wangkang
*
*/
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { /**
* 描述 : 构造函数
*
* @param request 请求对象
*/
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
} @Override
public String getHeader(String name) {
String value = super.getHeader(name);
return HtmlUtils.htmlEscape(value);
} @Override
public String getParameter(String name) {
String value = super.getParameter(name);
return HtmlUtils.htmlEscape(value);
} @Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
if (values != null) {
int length = values.length;
String[] escapseValues = new String[length];
for (int i = 0; i < length; i++) {
escapseValues[i] = HtmlUtils.htmlEscape(values[i]);
}
return escapseValues;
}
return super.getParameterValues(name);
} }

2.创建XssStringJsonSerializer类

其次是涉及到json转换的地方,也一样需要进行转意,比如,rerquestBody,responseBody


/**
* XssStringJsonSerializer.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package org.itkk.udf.core.xss; import java.io.IOException; import org.springframework.web.util.HtmlUtils; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; /**
* 描述 : 基于xss的JsonSerializer
*
* @author wangkang
*
*/
public class XssStringJsonSerializer extends JsonSerializer<String> { @Override
public Class<String> handledType() {
return String.class;
} @Override
public void serialize(String value, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
if (value != null) {
String encodedValue = HtmlUtils.htmlEscape(value);
jsonGenerator.writeString(encodedValue);
}
} }

3.创建Bean

在启动类中,创建XssObjectMapper的bean,替换spring boot原有的实例,用于整个系统的json转换.


/**
* 描述 : xssObjectMapper
*
* @param builder builder
* @return xssObjectMapper
*/
@Bean
@Primary
public ObjectMapper xssObjectMapper(Jackson2ObjectMapperBuilder builder) {
//解析器
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
//注册xss解析器
SimpleModule xssModule = new SimpleModule("XssStringJsonSerializer");
xssModule.addSerializer(new XssStringJsonSerializer());
objectMapper.registerModule(xssModule);
//返回
return objectMapper;
}

4.创建XssFilter

首先是拦截所有的请求,然后在doFilter方法中,将HttpServletRequest强制类型转换成XssHttpServletRequestWrapper

然后传递下去.


/**
* XssFilter.java
* Created at 2016-09-19
* Created by wangkang
* Copyright (C) 2016 egridcloud.com, All rights reserved.
*/
package org.itkk.udf.core.xss; import java.io.IOException; 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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 描述 : 跨站请求防范
*
* @author wangkang
*
*/
@WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true)
public class XssFilter implements Filter { /**
* 描述 : 日志
*/
private static final Logger LOGGER = LoggerFactory.getLogger(XssFilter.class); @Override
public void init(FilterConfig filterConfig) throws ServletException { } @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
XssHttpServletRequestWrapper xssRequest =
new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
} @Override
public void destroy() {
} }

代码仓库 (博客配套代码)

结束

本文虽基于spring boot实现主题,但是思路是一致的,不限于任何框架.


想获得最快更新,请关注公众号

spring boot / cloud (一) 使用filter防止XSS的更多相关文章

  1. spring boot / cloud (二) 规范响应格式以及统一异常处理

    spring boot / cloud (二) 规范响应格式以及统一异常处理 前言 为什么规范响应格式? 我认为,采用预先约定好的数据格式,将返回数据(无论是正常的还是异常的)规范起来,有助于提高团队 ...

  2. spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法

    spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...

  3. spring boot / cloud (三) 集成springfox-swagger2构建在线API文档

    spring boot / cloud (三) 集成springfox-swagger2构建在线API文档 前言 不能同步更新API文档会有什么问题? 理想情况下,为所开发的服务编写接口文档,能提高与 ...

  4. spring boot / cloud (五) 自签SSL证书以及HTTPS

    spring boot / cloud (五) 自签SSL证书以及HTTPS 前言 什么是HTTPS? HTTPS(全称:Hyper Text Transfer Protocol over Secur ...

  5. spring boot / cloud (六) 开启CORS跨域访问

    spring boot / cloud (六) 开启CORS跨域访问 前言 什么是CORS? Cross-origin resource sharing(跨域资源共享),是一个W3C标准,它允许你向一 ...

  6. spring boot / cloud (七) 使用@Retryable来进行重处理

    spring boot / cloud (七) 使用@Retryable来进行重处理 前言 什么时候需要重处理? 在实际工作中,重处理是一个非常常见的场景,比如:发送消息失败,调用远程服务失败,争抢锁 ...

  7. spring boot / cloud (十五) 分布式调度中心进阶

    spring boot / cloud (十五) 分布式调度中心进阶 在<spring boot / cloud (十) 使用quartz搭建调度中心>这篇文章中介绍了如何在spring ...

  8. spring boot / cloud (八) 使用RestTemplate来构建远程调用服务

    spring boot / cloud (八) 使用RestTemplate来构建远程调用服务 前言 上周因家里突发急事,请假一周,故博客没有正常更新 RestTemplate介绍: RestTemp ...

  9. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

随机推荐

  1. 关于移动APP与Web APP的测试重点以及区别

    Web app测试重点: 1. 功能测试:功能的实现是否满足需求. 2. 性能测试: 2.1 链接速度测试:测试页面链接的速度 2.2 负载测试:web应用系统能允许多少个用户同时在线?超过这个数量会 ...

  2. background:rgba() 兼容ie8 用法

    background: rgba(255,255,255,.1);//火狐,谷歌等 filter:progid:DXImageTransform.Microsoft.gradient(startCol ...

  3. Android - DrawerLayout

    Android DrawerLayout 的使用 Android L Android Studio 1.4 从主视图左侧能抽出一个导航栏,效果图:  点击后弹出新界面:  新界面也可以抽出左侧导航栏 ...

  4. Kafka笔记——技术点汇总

    Table of contents Table of contents Overview Introduction Use cases Manual setup Assumption Configur ...

  5. Hadoop之HDFS及NameNode单点故障解决方案

    Hadoop之HDFS 版权声明:本文为yunshuxueyuan原创文章.如需转载请标明出处: http://www.cnblogs.com/sxt-zkys/QQ技术交流群:299142667 H ...

  6. 使用Go和Let's Encrypt证书部署HTTPS

    为什么要使用HTTPS?使用HTTPS的途径有哪些?如何用Go来部署HTTPS?拿出你的小本本,你要的干货都在这儿! HTTPS的好处我们已在之前的文章中提高好多.它加密浏览器和服务器之间的流量,保障 ...

  7. 【AngularJS】学习资料

    1. http://www.cnblogs.com/lcllao/tag/AngularJs/ http://www.ituring.com.cn/article/13474 http://www.a ...

  8. vue获取下拉框值

    vue获取下拉框的值,用vue-modle,只有点击下拉框的值才会赋值到下拉框中,初始时下拉框没有数据,而改用$event就不会出现这样的问题,下面看代码以及图解: v-model解决方式: < ...

  9. [补档]暑假集训D2总结

    %dalao https://hzoi-mafia.github.io/2017/07/26/17/ (纪念我已死去的github) 大佬AntiLeaf来讲概率&期望,然后--成功变为 不可 ...

  10. 如何编写轻量级 CSS 框架

    Github 地址: https://github.com/nzbin/snack Demo 演示: https://nzbin.github.io/snack/ 前言 这篇文章我已经酝酿了半年之久, ...