【快学SpringBoot】过滤XSS脚本攻击(包括json格式)
若图片查看异常,请前往掘金查看:https://juejin.im/post/5d079e555188251ad81a28d9
XSS攻击是什么
XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
简而言之,就是作恶用户通过表单提交一些前端代码,如果不做处理的话,这些前端代码将会在展示的时候被浏览器执行。
如何避免XSS攻击
解决XSS攻击,可以通过后端对输入的数据做过滤或者转义,使XSS攻击代码失效。
代码实现
对于过滤XSS脚本的代码,通过搜索引擎可以搜索到很多,但似乎都不是那么全面。基本上都是只能过滤querystring(表单类型)类型的入参,而不能过滤json类型的入参。其实,在现在的开发中,更多的是使用json类型做数据交互。下面就直接贴代码了:
新建XssAndSqlHttpServletRequestWrapper.java
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* @author Happy
* 防止XSS攻击
*/
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = request.getParameter(name);
if (!StringUtils.isEmpty(value)) {
value = StringEscapeUtils.escapeHtml4(value);
}
return value;
}
@Override
public String[] getParameterValues(String name) {
String[] parameterValues = super.getParameterValues(name);
if (parameterValues == null) {
return null;
}
for (int i = 0; i < parameterValues.length; i++) {
String value = parameterValues[i];
parameterValues[i] = StringEscapeUtils.escapeHtml4(value);
}
return parameterValues;
}
}
这里重写了两个方法:getParameter和getParameterValues,getParameter方法是直接通过request获得querystring类型的入参调用的方法。如果是通过springMVC注解类型来获得参数的话,走的是getParameterValues的方法。大家可以通过打印一个输出来验证一下。
StringEscapeUtils.escapeHtml4这个方法来自Apache的工具类,maven坐标如下:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.4</version>
</dependency>
新建XssFilter.java
过滤的代码写完了,下面就是在一个filter中应用该代码。
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author Happy
*/
@WebFilter
@Component
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(req);
chain.doFilter(xssRequestWrapper, response);
}
@Override
public void destroy() {
}
/**
* 过滤json类型的
* @param builder
* @return
*/
@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;
}
}
过滤表单类型的代码已经完成(xssObjectMapper这个是后面过滤json类型才用到的)。下面来实现过滤json类型的代码:
新建XssStringJsonSerializer.java
代码如下:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.apache.commons.text.StringEscapeUtils;
import java.io.IOException;
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 = StringEscapeUtils.escapeHtml4(value);
jsonGenerator.writeString(encodedValue);
}
}
}
这里是通过修改SpringMVC的json序列化来达到过滤xss的目的的。其实也可以通过第一种方法,重写getInputStream方法来实现,这里我就不做演示了(通过json类型传参会走getInputStream方法,通过重写该方法打印输出可以证明)。
测试
TestController.java
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Happy
*/
@RestController
@RequestMapping(value = "/test")
public class TestController {
@PostMapping(value = "/xss")
public Object test(String name) {
System.out.println(name);
return name;
}
@PostMapping(value = "/json")
public Object testJSON(@RequestBody Param param) {
return param;
}
@GetMapping(value = "/query")
public Object testQuery(String q){
return q;
}
@PostMapping(value = "/upload")
public Object upload(MultipartFile file){
System.out.println(file.getOriginalFilename());
return "OK";
}
}
下面通过postman测试下效果:
可以看到,js代码已经经过转义。转义过后的代码,即使前端读取过去了,也不会被浏览器执行的。
【快学SpringBoot】过滤XSS脚本攻击(包括json格式)的更多相关文章
- SpringBoot过滤XSS脚本攻击
XSS攻击是什么 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安 ...
- 第二百六十五节,xss脚本攻击介绍
xss脚本攻击介绍 Cross-Site Scripting(XSS)是一类出现在 web 应用程序上的安全弱点,攻击者可以通过 XSS 插入一 些代码,使得访问页面的其他用户都可以看到,XSS 通常 ...
- XSS脚本攻击漫谈
XSS跨站脚本攻击一直都被认为是客户端 Web安全中最主流的攻击方式.因为 Web环境的复杂性以及 XSS跨站脚本攻击的多变性,使得该类型攻击很难彻底解决.那么,XSS跨站脚本攻击具体攻击行为是什 ...
- xss脚本攻击
xss脚本攻击不仅仅只是alert(1)就算完了,xss脚本攻击真正的用处是盗取普通用户的cookie,或者盗取管理员的cookie. xss分类(类型): 1. 反射型xss2. 存储型xss3. ...
- JAVA覆写Request过滤XSS跨站脚本攻击
注:本文非本人原著. demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca 如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼.为什么呢. ...
- 【快学SpringBoot】Spring Cache+Redis实现高可用缓存解决方案
前言 之前已经写过一篇文章介绍SpringBoot整合Spring Cache,SpringBoot默认使用的是ConcurrentMapCacheManager,在实际项目中,我们需要一个高可用的. ...
- 【快学springboot】13.操作redis之String数据结构
前言 在之前的文章中,讲解了使用redis解决集群环境session共享的问题[快学springboot]11.整合redis实现session共享,这里已经引入了redis相关的依赖,并且通过spr ...
- 【快学springboot】12.实现拦截器
前言 之前在[快学springboot]6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,并且在文末还说了Web ...
- 【快学springboot】8.JPA乐观锁OptimisticLocking
介绍 当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的.为此,我们可以使用Java Persistence API提供的乐观锁定机制.它导致在同一时间对同一数据进行多次更新不会相互干扰 ...
随机推荐
- 定位布局 Stack 层叠组件 Stack 与 Align Stack 与 Positioned 实现
一.Flutter Stack 组件 Stack 表示堆的意思,我们可以用 Stack 或者 Stack 结合 Align 或者 Stack 结合 Positiond 来实现页面的定位布局 align ...
- 【PAT甲级】1091 Acute Stroke (30 分)(BFS)
题意: 输入四个正整数M,N,K,T(K<=60,M<=1286,N<=128),代表每片的高度和宽度,片数和最小联通块大小.输出一共有多少个单元满足所在联通块大小大于等于T. tr ...
- 传奇GOM引擎授权过期解决方法.
传奇GOM引擎授权过期解决方法 下载最新的GOM引擎,将里面的Key.Lic文件找出来,替换掉授权过期的版本,如果你本身是免费版最好是找同样的免费版的来覆盖. 如果你本身是免费版,但是却用的是商业版K ...
- stl_list复习
#include <iostream>#include <list>#include <algorithm>using namespace std; //底层结构是 ...
- 【代码总结】MYSQL数据库的常见操作
============================== MYSQL数据库的常见操作 ============================== 一.mysql的连接与关闭 -h:指定所连接的服 ...
- gitlab回退到某次commit——本地+远程
## 查看所有commits记录$ git log ## gitlab回退到某次commit$ git reset --hard 3018a546427e1f865524b82b488d6a2721d ...
- 使用13行Python代码实现四则运算计算器函数
原创的刷新行数记录的代码!!! 支持带小括号,支持多个连续+-号,如-7.9/(-1.2-++--99.3/-4.44)*---(2998.654+-+-+-(+1.3-7.654/(-1.36-99 ...
- 【PAT甲级】1043 Is It a Binary Search Tree (25 分)(判断是否为BST的先序遍历并输出后序遍历)
题意: 输入一个正整数N(<=1000),接下来输入N个点的序号.如果刚才输入的序列是一颗二叉搜索树或它的镜像(中心翻转180°)的先序遍历,那么输出YES并输出它的后序遍历,否则输出NO. t ...
- Linux vim中方向键变成字母的问题
使用Ubuntu Desktop 18.04 时 发现 vim 在编辑模式的时候,方向键变成了字母ABCD. 原因: Ubuntu预装的是vim tiny版本,安装vim full版本即可解决. 1. ...
- SpringMVC 入门demo
(1)新建Spring项目 (2)添加所需要的jar包 spring的5+2: spring-core.jar spring.beans.jar spring-context.jar spring-e ...