若图片查看异常,请前往掘金查看: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格式)的更多相关文章

  1. SpringBoot过滤XSS脚本攻击

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

  2. 第二百六十五节,xss脚本攻击介绍

    xss脚本攻击介绍 Cross-Site Scripting(XSS)是一类出现在 web 应用程序上的安全弱点,攻击者可以通过 XSS 插入一 些代码,使得访问页面的其他用户都可以看到,XSS 通常 ...

  3. XSS脚本攻击漫谈

    XSS跨站脚本攻击一直都被认为是客户端  Web安全中最主流的攻击方式.因为  Web环境的复杂性以及 XSS跨站脚本攻击的多变性,使得该类型攻击很难彻底解决.那么,XSS跨站脚本攻击具体攻击行为是什 ...

  4. xss脚本攻击

    xss脚本攻击不仅仅只是alert(1)就算完了,xss脚本攻击真正的用处是盗取普通用户的cookie,或者盗取管理员的cookie. xss分类(类型): 1. 反射型xss2. 存储型xss3. ...

  5. JAVA覆写Request过滤XSS跨站脚本攻击

    注:本文非本人原著. demo的地址:链接:http://pan.baidu.com/s/1miEmHMo 密码:k5ca 如何过滤Xss跨站脚本攻击,我想,Xss跨站脚本攻击令人为之头疼.为什么呢. ...

  6. 【快学SpringBoot】Spring Cache+Redis实现高可用缓存解决方案

    前言 之前已经写过一篇文章介绍SpringBoot整合Spring Cache,SpringBoot默认使用的是ConcurrentMapCacheManager,在实际项目中,我们需要一个高可用的. ...

  7. 【快学springboot】13.操作redis之String数据结构

    前言 在之前的文章中,讲解了使用redis解决集群环境session共享的问题[快学springboot]11.整合redis实现session共享,这里已经引入了redis相关的依赖,并且通过spr ...

  8. 【快学springboot】12.实现拦截器

    前言 之前在[快学springboot]6.WebMvcConfigurer配置静态资源和解决跨域里有用到WebMvcConfigurer接口来实现静态资源的映射和解决跨域请求,并且在文末还说了Web ...

  9. 【快学springboot】8.JPA乐观锁OptimisticLocking

    介绍 当涉及到企业应用程序时,正确地管理对数据库的并发访问是至关重要的.为此,我们可以使用Java Persistence API提供的乐观锁定机制.它导致在同一时间对同一数据进行多次更新不会相互干扰 ...

随机推荐

  1. 文件服务器之fastDFS

    FastDFS是一个开源的轻量级分布式文件系统,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合中小文件(建议范围:4KB < file ...

  2. 架设传奇时打开DBC数据库出错或读取DBC失败解决方法

    架设传奇时打开DBC数据库出错或读取DBC失败解决方法 DBC右键-属性-高级-管理员身份运行 即可

  3. RedisTemplate 获取过期时间的问题

    RedisTemplate redisTemplate; Long seconds = redisTemplate.opsForValue().getOperations().getExpire(&q ...

  4. SpringBoot2.x整合Shiro出现cors跨域问题(踩坑记录)

    1. Springboot如何跨域? 最简单的方法是: 定义一个配置CorsConfig类即可(是不是简单且无耦合到令人发指) @Configuration public class CorsConf ...

  5. spark实验(三)--Spark和Hadoop的安装(1)

    一.实验目的 (1)掌握在 Linux 虚拟机中安装 Hadoop 和 Spark 的方法: (2)熟悉 HDFS 的基本使用方法: (3)掌握使用 Spark 访问本地文件和 HDFS 文件的方法. ...

  6. opencv python:ROI 与 泛洪填充

    提取ROI区域,处理然后放回去: 泛洪填充 测试代码:显示一张图像,鼠标点击之后,会从该点开始进行填充,显示填充后的结果图像 注:二值图像的填充需要使用选项:cv2.FLOODFILL_MASK_ON ...

  7. Windows下MySQL5.7版本中修改编码为utf-8

    我们新安装的MySQL数据库默认的字符是 latin1 ,所以每次新建数据库都要修改字符,非常麻烦.所以我们必须将它改成UTF8字符的. 修改方法如下: 一.修改MySQL的my.ini 首先在 \P ...

  8. 【PAT甲级】1056 Mice and Rice (25 分)

    题意: 输入两个正整数N和M(<=1000),接着输入两行,每行N个数,第一行为每只老鼠的重量,第二行为每只老鼠出战的顺序.输出它们的名次.(按照出战顺序每M只老鼠分为一组,剩余不足M只为一组, ...

  9. 十、Spring中常用注解-分层整理

    1.@Controller: 标注展示层组件(Bean),但是目前该功能与 @Component 相同,用来创建处理http请求的对象   Spring4之后加入的注解,原来在@Controller中 ...

  10. 指令——mdadm

    Mdadm命令详解 Linux内核中有一个md(multiple devices)模块在底层管理RAID设备,它会在应用层给我们提供一个应用程序的工具mdadm ,mdadm是linux下用于创建和管 ...