使用AntiSamy拦截xss攻击

什么是Xss攻击

XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。

 

XSS 攻击的防御

XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码

也就是对提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。虽然对输入过滤可以被绕过,但是也还是会拦截很大一部分的XSS攻击。

AntiSamy介绍

OWASP是一个开源的、非盈利的全球性安全组织,致力于应用软件的安全研究。我们的使命是使应用软件更加安全,使企业和组织能够对应用安全风险作出更清晰的决策。目前OWASP全球拥有140个分会近四万名会员,共同推动了安全标准、安全测试工具、安全指导手册等应用安全技术的发展。

OWASP AntiSamy项目可以有好几种定义。从技术角度看,它是一个可确保用户输入的HTML/CSS符合应用规范的API。也可以这么说,它是个确保用户无法在HTML中提交恶意代码的API,而这些恶意代码通常被输入到个人资料、评论等会被服务端存储的数据中。在Web应用程序中,“恶意代码”通常是指 Javascript。同时层叠样式表(CSS)在调用Javascript引擎的时候也会被认为是恶意代码。当然在很多情况下,一些“正常”的HTML 和CSS也会被用于恶意的目的,所以我们也会对此予以处理。

官方网站:https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project

 

标准策略文件说明

antisamy-slashdot.xml

Slashdot (  http://www.slashdot.org/  )  是一个提供技术新闻的网站,它允许用户用有限  的  HTML  格式的内容匿名回帖。  Slashdot 不仅仅是目前同类中最酷的网站之一,而  且同时也曾是最容易被成功攻击的网站之一。更不幸的是,导致大部分用户遭受攻  击的原由是臭名昭着的  goatse.cx  图片  (  请你不要刻意去看  )  。  Slashdot 的安全策略非常严格:用户只能提交下列的  html  标签:  <b>, <u>, <i>,<a>,<blockquote>  ,并且还不支持  CSS.

因此我们创建了这样的策略文件来实现类似的功能。它允许所有文本格式的标签来  直接修饰字体、颜色或者强调作用。

antisamy-ebay.xml

众所周知,  eBay (  http://www.ebay.com/  )  是当下最流行的在线拍卖网站之一。它是一  个面向公众的站点,因此它允许任何人发布一系列富  HTML  的内容。  我们对  eBay  成为一些复杂  XSS  攻击的目标,并对攻击者充满吸引力丝毫不感到奇怪。由于  eBay  允许  输入的内容列表包含了比  Slashdot 更多的富文本内容,所以它的受攻击面也要大得多。下面的标签看起来是eBay允许的(  eBay  没有公开标签的验证规则)

antisamy-myspace.xml

MySpace ( http://www.myspace.com/  )  是最流行的一个社交网站之一。用户允许提交 几乎所有的他们想用的  HTML  和  CSS  ,只要不包含  JavaScript 。  MySpace  现在用一  个黑名单来验证用户输入的  HTML  ,这就是为什么它曾受到  Samy  蠕虫攻击  ( http://namb.la/)  的原因。  Samy  蠕虫攻击利用了一个本应该列入黑名单的单词  (eval)  来进行组合碎片攻击的,其实这也是  AntiSamy 立项的原因。

antisamy-anythinggoes.xml

也很难说出一个用这个策略文件的用例。如果你想允许所有有效的  HTML  和  CSS  元素输入(但能拒绝  JavaScript 或跟  CSS  相关的网络钓鱼攻击),你可以使用  这个策略文件。其实即使  MySpace 也没有这么疯狂。然而,它确实提供了一个很  好的参考,因为它包含了对于每个元素的基本规则,所以你在裁剪其它策略文件的  时候可以把它作为一个知识库。

个人可以定制策略: http://www.owasp.org/index.php/AntiSamy_Directives

 

JAVA中AntiSamy的使用

因为自己写过滤文件可能很多没有考虑到,所以我们使用antisamy-myspace-1.4.4.xml策略文件来过来

首先,老规矩,我们需要一个antisamy的jar包

使用Maven的,在pom.xml的dependencies中添加如下代码

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

将策略文件antisamy-myspace-1.4.4.xml放到和pom.xml平级目录下,添加XssCleanUtil工具类

@Slf4j
public class XssCleanUtil {
    private static Policy policy = null;

    /**
     * @desc 得到过滤规则
     * @author 杨小华
     * @create 2017/11/9 15:40
     **/
    public static Policy getPolicy() throws PolicyException {
        if (policy == null) {
            InputStream policyFile = XssCleanUtil.class.getResourceAsStream("/antisamy-myspace-1.4.4.xml");
            policy = Policy.getInstance(policyFile);
        }
        return policy;
    }

    /**
     * @desc 执行过滤
     * @author 杨小华
     * @create 2017/11/9 15:40
     **/
    public static String xssClean(String value) {
        if (StringUtils.isNotEmpty(value)) {
            AntiSamy antiSamy = new AntiSamy();
            try {
                final CleanResults cr = antiSamy.scan(value, getPolicy());
                //安全的HTML输出
                value = cr.getCleanHTML();
            } catch (ScanException e) {
                log.error("过滤XSS异常");
            } catch (PolicyException e) {
                log.error("加载XSS规则文件异常: " + e.getMessage());
            }
        }
        return value;
    }

重写request,新建一个类XssHttpServletRequestWrapper ,继承HttpServletRequestWrapper,我们需要重写getParameterValues()方法、getParameter()方法、getHeader()方法。

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }

    /**
     * @desc 过滤getParameterValues
     * @author 杨小华
     * @create 2017/11/9 14:50
     **/
    public String[] getParameterValues(String parameter) {
        // 返回值之前 先进行过滤
        String[] values = super.getParameterValues(parameter);
        if (values == null) {
            return null;
        }
        int count = values.length;
        String[] encodedValues = new String[count];
        for (int i = 0; i < count; i++) {
            encodedValues[i] = XssCleanUtil.xssClean(values[i]);
        }
        return encodedValues;
    }

    /**
     * @desc 过滤getParameter
     * @author 杨小华
     * @create 2017/11/9 14:50
     **/
    public String getParameter(String parameter) {
        // 返回值之前 先进行过滤
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return XssCleanUtil.xssClean(value);
    }

    /**
     * @desc 过滤getHeader
     * @author 杨小华
     * @create 2017/11/9 15:31
    **/
    public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null)
            return null;
        return XssCleanUtil.xssClean(value);
    }
}

自定义XssFilter类,该类必须实现Filter类,在XssFilter类中实现doFilter函数。

public class XssFilter implements Filter {
    FilterConfig filterConfig = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    public void destroy() {
        this.filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
    }
}

配置web.xml

<!--xss拦截器-->
<filter>
    <filter-name>XssSqlFilter</filter-name>
    <filter-class>com.lemo.erp.util.XssFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>XssSqlFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

好了,到此为止,我们的AntiSamy就成功添加到项目了。

还有CSRF 防御方案总结下,无外乎三种:

  1. 用户操作限制,比如验证码;
  2. 请求来源限制,比如限制 HTTP Referer 才能完成操作;
  3. token 验证机制,比如请求数据字段中添加一个 token,响应请求时校验其有效性;

第一种方案明显严重影响了用户体验,而且还有额外的开发成本;第二种方案成本最低,但是并不能保证 100% 安全,而且很有可能会埋坑;第三种方案,可取!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值