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坐标如下:

org.apache.commons

commons-text

1.4

新建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 {

@Override

public Class 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代码已经经过转义。转义过后的代码,即使前端读取过去了,也不会被浏览器执行的。

java 过滤脚本_【快学SpringBoot】过滤XSS脚本攻击(包括json格式)相关推荐

  1. 3d 强制添加脚本_每日学点---Jenkins执行脚本权限问题

    问题: Jenkins执行shell时提示权限不够 和 sudo:没有终端存在,且未指定 askpass 程序 解释 Jenkins服务是默认是jenkins用户启动的,权限较小,需要赋予sudo权限 ...

  2. jpa mysql乐观锁_【快学springboot】8.JPA乐观锁OptimisticLocking

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

  3. 「快学springboot」SpringBoot多环境配置文件

    [原创] Happyjava 2019-06-18 07:01:00 往期文章 「快学Docker」Docker简介.安装和Hello World实现 「快学springboot」使用springbo ...

  4. java 7年_笃学私教:7年Java开发(月薪37K)分享正确的自学路线,不喜勿喷!

    原标题:笃学私教:7年Java开发(月薪37K)分享正确的自学路线,不喜勿喷! 趁着昨晚空闲和今早的时间,编辑这一篇帖子,写下当初我自学Java走的弯路,希望大家引以为戒,不要多走前人走过的弯路,浪费 ...

  5. datatables 树形表格 java数据组装_实学:Java开发自己的博客系统-第三十篇(后台添加栏目功能-4)...

    上一节已经显示了表格内容.读者玩有些网站的话,会发现很多表格有排序.分页.搜索功能,我们这一节先来做以下这些,因为如果导入一个库:DataTables,那么这些事情都是简单到你无法想象的事情. 跟我来 ...

  6. linux shc shell脚本_使用shc工具加密shell脚本详解

    Shc可以用来对shell脚本进行加密,可以将shell脚本转换为一个可执行的二进制文件.经过shc对shell脚本进行加密后,会同时生成两种个新的文件,一个是加密后的可执行的二进制文件(文件名以.x ...

  7. java获取list redis_【快学springboot】14.操作redis之list

    前言 之前讲解了springboot(StringRedisTemplate)操作redis的string数据结构,这篇文章将会讲解list数据结构 list数据结构具有的操作 下图列出了redis ...

  8. java字符串去掉一头一尾_快学Scala第13章----集合

    本章要点 所有集合都扩展自Iterable特质 集合有三大类:序列.集.映射 对于几乎所有集合类,Scala都同时提供了可变的和不可变的版本 Scala列表要么是空的,要么拥有一头一尾,其中尾部本身又 ...

  9. java filter注入_如何使用Filter过滤请求中的SQL注入攻击

    在doFilter方法中编写判断逻辑 public void doFilter(ServletRequest request, ServletResponse response, FilterChai ...

最新文章

  1. 刘烨:家里官方语言是中文 听不懂娘仨说法语
  2. 【中级软考】什么是McCabe测量法(McCabe复杂性度量、环路度量。计算有向弧数、结点数、强连通分量个数)
  3. 史上最详细Docker安装Elasticsearch、ik分词器、可视化工具,每一步都带有步骤图!!!
  4. 不能卸载java_无法卸载注入的DLL
  5. 单实例oracle ha,Oracle单实例启动多个实例
  6. 一文读懂什么是DDS
  7. matlab自带python_在matlab中直接在python中使用sklearn
  8. Alpha冲刺随笔—:第一天
  9. 《Javascript高级程序设计》读书笔记(1-3章)
  10. 阿里云服务器搭建私人云盘
  11. 4星|《经济学人》熊彼特系列2017合集:美国人逐渐按自己的职业及社会价值而聚居至不同区域...
  12. 思科模拟器中的交换机使用方法
  13. 翻译: 巴菲特公式:睡觉比醒来更聪明
  14. Gitee码云使用与Git安装、基本使用介绍
  15. WPF实现炫酷Loading控件
  16. 【计算机网络】网线规格的鉴别与接线方法
  17. 自制STLinkV2.1
  18. 映射网络驱动器错误:无法找到网络名,该设备或资源未设置为接受端口,“文件和打印机共享(SMB)”上的连接。
  19. LiveGBS国标流媒体GB28181微信无插件直播如何实现跨域鉴权
  20. mysql医学数据库_医学离线数据库 1.0

热门文章

  1. 多机器使用setnx 设置同一个key_Redisson分布式锁的简单使用
  2. div 图片滚动 / 文字滚动
  3. SharedPreferences详解
  4. 跌倒识别 摔倒识别 -lightweight_openpose
  5. CentOS7 源码编译安装NodeJS 最新版本Shell脚本
  6. Shiro并发登录人数控制遇到的问题和解决
  7. win10创建新的计算机用户名和密码错误,Win10开机提示用户名或密码不正确现象的解决办法...
  8. python的基本数据结构_Python学习笔记——基本数据结构
  9. fp算法例题_机器学习(九)—FP-growth算法
  10. python中文文本分析_python使用snownlp进行中文文本处理以及分词和情感分析 - pytorch中文网...