AntiSamy:防 XSS 攻击的一种解决方案使用教程

  • 1. XSS 介绍
  • 2. AntiSamy 介绍
  • 3. AntiSamy 使用
    • 3.1 导入依赖
    • 3.2 选择策略文件
    • 3.3 SpringBoot 整合 AntiSamy 使用

1. XSS 介绍

XSS 是跨站脚本攻击(Cross Site Scripting) 的简称,为不和 CSS(Cascading Style Sheets) 混淆,故将跨站脚本攻击缩写为 XSS. XSS 是指恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。有点类似于 SQL 注入。当网站攻击者发现这个漏洞,并攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容。

XSS 攻击分为两种类型

  • 持久型:XSS 攻击代码被存储到服务器的数据库中,隐秘性很高。例如,当攻击者在评论或留言板注入 XSS 攻击代码,而帖子或博客被服务器存储下来,帖子的评论或留言板自然也就被持久化到服务器的数据库中,这里面就包含了 XSS 攻击代码。当其他用户浏览这个帖子的时候,XSS 攻击代码便开始在用户的浏览器中解析并执行。
  • 反射型:反射型 XSS 又称为非持久型 XSS,这种攻击方式具有一次性的特点。例如,攻击者将包含 XSS 代码的恶意链接发送给用户,当用户访问链接时,服务器收到用户请求并进行处理,再将包含 XSS 代码的数据返回给用户的浏览器,那么用户浏览器解析包含 XSS 代码的数据时,就会触发 XSS 漏洞。
  • DOM 型:区别于以上两种类型,DOM 型 XSS 攻击不经过服务器,它是由攻击者直接构造一个包含 XSS 攻击代码的 URL,然后让目标用户去访问这个 URL,用户的浏览器在处理这个响应的时候,DOM 型对象就会处理 XSS 代码,触发 XSS 漏洞。

2. AntiSamy 介绍

因此为了避免这个漏洞给网站的用户带来的危害,OWASP 组织开源了一个叫做 AntiSamy 的项目,帮助我们的网站防御 XSS 攻击。它通过对用户输入的 HTML / CSS / JavaScript 等内容进行检验和清理,确保输入符合应用规范。AntiSamy 被广泛应用于 Web 服务对存储型和反射型 XSS 的防御中。

官方给出的关于 AntiSamy 的介绍是这样的:

AntiSamy 是一个 API 或 库 ,可以帮助我们开发者确保客户端不会在他们提供的 HTML 中提供恶意的代码,这些 HTML 用于保存在服务器上的配置文件、注释等。关于 web 应用程序的术语“恶意代码”通常指“JavaScript”。大多数情况下,CSS 只有在调用 JavaScript 时才被认为是恶意的。然而,在许多情况下,“正常的” HTML 和 CSS 可以被恶意使用。

3. AntiSamy 使用

3.1 导入依赖

AntiSamy 的 maven 坐标:

<dependency><groupId>org.owasp.antisamy</groupId><artifactId>antisamy</artifactId><version>1.6.2</version>
</dependency>

3.2 选择策略文件

AntiSamy 预定义了一些策略文件,这些策略文件它们代表了允许用户提供 HTML (可能还有CSS) 格式化信息的典型应用场景,我们可以根据自己的应用场景选择合适的策略文件。具体的策略文件有以下几种:

1、antisamy-slashdot.xml

  • Slashdot 是一个技术新闻网站,它允许用户匿名回复非常有限的 HTML 标记的新闻帖子。现在,Slashdot 不仅是最酷的网站之一,它也是一个受到许多不同成功攻击的网站。
  • Slashdot 的规则相当严格:用户只能提交以下 <b>, <u>, <i>, <a>, <blockquote> 这些 HTML 标记,不能提交 CSS.
  • 因此,antisamy-slashdot.xml 文件支持类似的功能,所有直接对字体、颜色或重点进行操作的文本格式标记都是允许的,但是不允许 CSS 和 JavaScript 标记出现。

2、antisamy-ebay.xml

  • eBay 是世界上最受欢迎的在线拍卖网站,它是一个公共站点,因此任何人都可以发布包含丰富 HTML 内容的清单。考虑到 eBay 作为一个有吸引力的目标,它受到一些复杂的 XSS 攻击并不奇怪。清单被允许包含比 Slashdot 更丰富的内容——所以它的攻击面相当大。
  • 因此,antisamy-ebay.xml 策略文件提供的策略是支持丰富的 HTML 标记,但是不支持 CSS 标记 和 JavaScript 标记。

3、antisamy-myspace.xml

  • MySpace 是一个曾经非常受欢迎的社交网站,用户可以提交几乎所有他们想要的 HTML 和CSS ——只要不包含 JavaScript. MySpace 使用一个单词黑名单来验证用户的 HTML,这就是为什么他们会受到臭名昭著的 Samy 蠕虫的攻击。Samy 蠕虫使用碎片攻击和一个应该被列入黑名单的词(eval)——是这个项目的灵感来源。
  • 因此,antisamy-myspace.xml 策略文件提供的策略是支持非常丰富的 HTML 和 CSS 标记,但是不支持 JavaScript 标记。

4、antisamy-anythinggoes.xml

  • 如果想允许每一个有效的 HTML 和 CSS 元素(但是不允许 JavaScript 或明显的 CSS 相关的钓鱼攻击),你可以使用这个策略文件。它包含每个元素的基本规则,所以在使用定制其他策略文件时,可以将它用作知识库。

5、antisamy-tinymce.xml

  • 只允许文本格式通过,相对比较安全。

6、antisamy.xml

  • 默认规则,允许大部分 HTML 标记,不允许 JavaScript 标记出现。

3.3 SpringBoot 整合 AntiSamy 使用

工程的目录结构如下:

第一步,创建 maven 工程 antiSamy_demo 并配置 pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.hzz</groupId><artifactId>antiSamy_demo</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.owasp.antisamy</groupId><artifactId>antisamy</artifactId><version>1.6.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>

第二步,创建 application.yml 文件

server:port: 9000

第三步,创建策略文件 /resources/antisamy-slashdot.xml,策略文件可以直接从 antisamy jar 包下复制

第四步,创建实体类 User

package com.hzz.entity;import lombok.Data;@Data
public class User {private int id;private String name;private int age;
}

第五步,创建 UserController

package com.hzz.controller;import com.hzz.entity.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@RequestMapping("/save")public String save(User user){System.out.println("UserController save.... " + user);return user.getName();}
}

第六步,创建 /resources/static/index.html 页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form method="post" action="/user/save">id:<input type="text" name="id"><br>name:<input type="text" name="name"><br>age:<input type="text" name="age"><br><input type="submit" value="submit">
</form>
</body>
</html>

第七步,创建过滤器,用于过滤所有提交到服务器的请求参数

package com.hzz.filter;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;//过滤所有提交到服务器的请求参数
public class XssFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;//传入重写后的RequestfilterChain.doFilter(new XssRequestWrapper(request), servletResponse);}
}

过滤器 XssFilter 并没有直接进行请求参数的过滤清理,而是直接放行。其实,过滤清理的工作是在另外一个类 XssRequestWrapper 中进行的,当上面的过滤器放行时需要调用filterChain.doFilter() 方法,此方法需要传入请求 request 对象,此时我们可以将当前的 request 对象进行包装,而 XssRequestWrapper 就是 request 对象的包装类,在过滤器放行时会自动调用包装类的 getParameterValues 方法,我们可以在包装类的 getParameterValues 方法中进行统一的请求参数过滤清理。

XssRequestWrapper 包装类实现如下

package com.hzz.filter;import org.owasp.validator.html.*;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.UnsupportedEncodingException;public class XssRequestWrapper extends HttpServletRequestWrapper {/*** 策略文件:需要将要使用的策略文件放到项目资源文件路径*/private static String antiSamyPath = XssRequestWrapper.class.getClassLoader().getResource( "antisamy-ebay.xml").getFile();public static Policy policy = null;static {//指定策略文件try {policy = Policy.getInstance(java.net.URLDecoder.decode(antiSamyPath, "utf-8")); //我的项目路径带有中文,需要转码,否则会报错,如果你的路径都是英文则忽略转码过程} catch (PolicyException | UnsupportedEncodingException e) {e.printStackTrace();}}/*** Antisamy 过滤数据* @param taintedHTML 需要进行过滤的数据* @Return 返回过滤后的数据*/private String xssClean(String taintedHTML) {try {//使用AntiSamy 进行过滤AntiSamy antiSamy = new AntiSamy();CleanResults cr = antiSamy.scan(taintedHTML, policy);taintedHTML = cr.getCleanHTML();} catch (ScanException e) {e.printStackTrace();} catch (PolicyException e) {e.printStackTrace();}return taintedHTML;}public XssRequestWrapper(HttpServletRequest request) {super(request);}@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);if (values == null) {return null;}int len = values.length;String[] newArray = new String[len];for (int j = 0; j < len; j++) {System.out.println("Antisamy 过滤清理,清理之前的参数值:"+values[j]);//过滤清理newArray[j] = xssClean(values[j]);System.out.println("Antisamy 过滤清理,清理之后的参数值:"+newArray[j]);}return newArray;}
}

第八步,为了使上面定义的过滤器生效,需要创建配置类,用于初始化过滤器对象

package com.hzz.config;import com.hzz.filter.XssFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//配置跨站攻击过滤器
@Configuration
public class AntiSamyConfiguration {@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new XssFilter());filterRegistrationBean.addUrlPatterns("/*");filterRegistrationBean.setOrder(1);return filterRegistrationBean;}
}

第九步,创建启动类并启动项目,访问网站首页地址 http://localhost:9000/index.html

package com.hzz;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class AntiSamyApp {public static void main(String[] args) {SpringApplication.run(AntiSamyApp.class, args);}
}

第十步,输入测试数据,并观察后台打印结果



从上图可以看到,测试的 XSS 攻击代码直接被清理掉了,服务器返回给浏览器的结果中没有 XSS 代码,不会被浏览器执行,成功避免了 XSS 攻击。

升级一下:

之前,我们在进行请求参数过滤时只是在包装类的 getParameterValues 方法中进行了处理,真实项目中可能用户提交的数据在请求头中,也可能用户提交的是 json 数据,所以如果考虑所有情况,我们可以在包装类中的多个方法中都进行清理处理即可,在 XssRequestWrapper 实现类中新增以下几个方法:

@Override
public String getParameter(String paramString) {String str = super.getParameter(paramString);if (str == null) {return null;}System.out.println("Antisamy 过滤清理,清理之前的参数值:"+str);//过滤清理str = xssClean(str);System.out.println("Antisamy 过滤清理,清理之后的参数值:"+str);return str;
}@Override
public String getHeader(String paramString) {String str = super.getHeader(paramString);if (str == null) {return null;}System.out.println("Antisamy 过滤清理,清理之前的参数值:"+str);//过滤清理str = xssClean(str);System.out.println("Antisamy 过滤清理,清理之后的参数值:"+str);return str;
}@Override
public Map<String, String[]> getParameterMap() {Map<String, String[]> requestMap = super.getParameterMap();for (Map.Entry<String, String[]> me : requestMap.entrySet()) {String[] values = me.getValue();for (int i = 0; i < values.length; i++) {System.out.println("Antisamy 过滤清理,清理之前的参数值:"+values[i]);//过滤清理values[i] = xssClean(values[i]);System.out.println("Antisamy 过滤清理,清理之后的参数值:"+values[i]);}}return requestMap;
}

AntiSamy:防 XSS 攻击的一种解决方案使用教程相关推荐

  1. tp5防止sql注入mysql_TP5框架 《防sql注入、防xss攻击》

    版权声明:本文为博主原创文章,转载请注明原文出处! https://blog.csdn.net/qq_23375733/article/details/86606630 如题:tp5怎么防sql注入 ...

  2. 使用AntiSamy拦截xss攻击

    什么是Xss攻击 XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中.比如这些代码包括HTML代码和客户端脚本.攻击者利用XSS漏洞旁路掉访 ...

  3. 使用antisamy防范XSS攻击及常用antisamy策略文件

    本文提及的XML策略文件下载地址:http://download.csdn.net/detail/softwave/9716400 antisamy的maven依赖: <dependency&g ...

  4. SpringBoot防XSS攻击

    1 . pom中增加依赖 <!-- xss过滤组件 --> <dependency><groupId>org.jsoup</groupId><ar ...

  5. springboot2.x使用Jsoup防 XSS 攻击

    后端应用经常接收各种信息参数,例如评论,回复等文本内容.除了一些场景下面,可以特定接受的富文本标签和属性之外(如:b,ul,li,h1, h2, h3-),需要过滤掉危险的字符和标签,防止xss攻击. ...

  6. post攻击 xxs_[BUGCASE]CI框架的post方法对url做了防xss攻击的处理引发的文件编码错误...

    一.问题描述 页面报错,没法下载 二.问题分析 1.初步分析 通过查看相关代码可以了解到文件下载的过程如下: 取到下载链接中的mid参数 对mid先后进行url解码和base64解码 将解码后的字符串 ...

  7. 防Xss攻击,包含富文本编辑器的处理

    为什么80%的码农都做不了架构师?>>>    众所周知,让用户在富文本编辑器中进行自己的输入绝对不是一个明智的选择,但是有的时候又没有办法,所以只有一条原则来保证系统的安全性,那就 ...

  8. java防XSS攻击的 关键词过滤实现

    继承HttpServletRequestWrapper,实现对请求参数的过滤/*** xss请求适配器*/ public class XssHttpServletRequestWrapper exte ...

  9. Web安全:X-XSS-Protection头(防XSS攻击设置)

    1.参考资料链接:https://www.freebuf.com/articles/web/138769.html 2.X-XSS-Protection头的三个值 0: 表示关闭浏览器的XSS防护机制 ...

最新文章

  1. Vue mixins(混入) 附代码示例详解
  2. 如何从头开始构建自己的Linux Dotfiles Manager
  3. 【CVPR2022】双曲图像分割
  4. python coding_python开头的coding设置方法
  5. CTF(pwn)-格式化字符串漏洞讲解(二) --攻防世界CGfsb
  6. Academic English Reading Notes
  7. sort()排序(Comparable、Comparator)
  8. 使用软碟通安装 CentOS Stream 会遇到哪些问题
  9. C# winform中ListView用法
  10. golang 学习记录
  11. 使用apache搭建tomcat集群
  12. 计算机d盘的权限怎么解决,D盘没权限,不能删除更改任何文件解决方法
  13. [工具] CuteMarkEd
  14. 绝大部分人都错误的把赚钱或者人生都放在依靠外界
  15. 小米主办HBaseCon亚洲峰会,打造世界一流的“工程师理想乐园”
  16. 《数字图像处理 第三版》(冈萨雷斯)——第十章 图像分割
  17. 【小程序】小程序开发工具的主要环境设置
  18. 1024info .php,GitHub - dingusxp/code1024
  19. 动态规划背包问题matlab,动态规划解决01背包问题
  20. 第14课:走向技术管理者的4种方式

热门文章

  1. 从零开始学习CANoe(八)—— IG 模块
  2. Mondriaan's Dream
  3. 动漫插画网课网课排名
  4. AMBA协议——APB协议
  5. Python常用的数据处理库有哪些?
  6. KBP310-ASEMI插件整流桥3A 1000V
  7. java如何写一个简单的定时任务?
  8. android状态栏透明!6年菜鸟开发面试字节跳动安卓研发岗,年薪50W
  9. django-simple-captcha 使用 以及添加动态ajax刷新验证
  10. Matplotlib python 学习笔记2