什么是XSS?

XSS(Cross Site Scripting),即跨站脚本攻击,是一种常见于web
application中的计算机安全漏洞。XSS通过在用户端注入恶意的可运行脚本,若服务器端对用户输入不进行处理,直接将用户输入输出到浏览器,则浏览器将会执行用户注入的脚本。

例如:有一个input输入框,要求用户输入名字,用户输入lily<script>alert("hello
world")</script>,服务器接收到用户的输入,并且直接将用户输入输出到页面上,则会有hello world
的alert对话框出现。如果说这是XSS黑客的自娱自乐,那么盗取用户信息的XSS就不那么友好了。如果用户通过注入脚本,盗取你的用户信息如cookie的内容,仿冒正常用户,进行相应的操作,则危害会更大。获取用户的cookie信息非常简单,只需要使用js获取document.cookie,即可以得到。为了便于分析,我们将在用户输入名字框中输入:lily<script>alert(document.cookie)</script>,则你就可以看到你的cookie信息显示在alert对话框中了。

XSS的分类

根据XSS造成的影响,可以将XSS分为非持久型和持久型。

1.非持久型,也叫反射型XSS。通过GET和POST方法,向服务器端输入数据。用户输入的数据通常被放置在URL的query
string中,或者是form
数据中。如果服务器端对输入的数据不进行过滤,验证或编码,就直接将用户输入的信息直接呈现给客户,则可能会造成反射型XSS。反射型XSS是比较普遍的XSS,其危害程度通常被认为较小。但是某些反射型XSS造成的后果会很严重,如在输入框的name中输入<meta
http-equiv="refresh" content="5"
/>,服务器不加处理,将name的值直接送到浏览器,则浏览器会每5秒自动刷新一次。严重者会导致服务器崩溃。

2.持久型,也叫存储型XSS。通常是因为服务器端将用户输入的恶意脚本没有通过验证就直接存储在数据库,并且每次通过调用数据库的方式,将数据呈现在浏览器上。则该XSS跨站脚本攻击将一直存在。若其他用户访问该页面,则恶意脚本就会被触发,用于盗取其他用户的私人信息。

常用XSS方式分为以下几种:
1. 输入框中直接输入恶意脚本,如:

><script>alert(document.cookie)</script>

2. 输入框中输入html标签,在标签中嵌入恶意脚本,如src,href,css style等。

<IMG SRC="javascript:alert('XSS');">;
<BODY BACKGROUND="javascript:alert('XSS')">
<STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI>XSS</br>

3.将恶意脚本注入在event事件中,如onClick,onBlur,onMouseOver等事件。

<a onmouseover="alert(document.cookie)">xxs link</a>

4. 在remote style sheet,javascript中,如

<LINK REL="stylesheet" HREF="javascript:alert('XSS');">
<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>

5. META 标签,如

<meta http-equiv="refresh" content="5" />
<META HTTP-EQUIV="Set-Cookie" Content="USERID=<SCRIPT>alert('XSS')</SCRIPT>">

如何预防以上两种XSS攻击?
1. 在输入流中截住form data中的恶意脚本
     研究两种XSS攻击,如反射型和存储型XSS攻击,其恶意脚本都是来自用户的输入。因此,可以使用过滤用户输入的方法对恶意脚本进行过滤。对简单的HTTP请求,一般使用GET和POST方法。当使用GET时,用户输入的数据将被放入地址栏的URL中,如:http://xxxx?name1=value1&name2=value2…..。其中,URL之后会放入键值对,对应name1的值为value1,name2的值为value2,等等。而对于POST方法,则用户输入数据仍然以name1=value1&name2=value2.。。。,但是数据键值对不会放进URL之后,而是放进了request的body中。因此,我们得到一个结论,所有的数据都存储在request中,我们可以截下进入server的每一个request,对用户的输入数据进行恶意脚本清理。其中有效的一个方法就是使用spring的filter。代码示例如下,在web.xml中加入以下代码段:
<filter>
        <filter-name>XSS</filter-name>
        <filter-class>com.springapp.domain.XssFilter</filter-class>
    </filter>

<filter-mapping>
        <filter-name>XSS</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
其中XssFilter为自定义的class,该类必须实现Filter类,在XssFilter类中实现doFilter函数。

public class XssFilter implements Filter {
    private FilterConfig filterConfig;

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

@Override
    public
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new RequestWrapper((HttpServletRequest) request), new ResponseWrapper((HttpServletResponse) response));

}

@Override
    public void destroy() {
        this.filterConfig = null;
    }
}
     那么我们怎样对每个request都进行过滤操作呢?怎么样对用户输入的数据进行操作呢?form数据都存储在什么地方传给servlet的呢?
     通常情况下,可以通过调用request.getParameter来获得单个对应name对应的value。若form的传入参数中,一个name值对应多个value,则可以使用request.getParameterValues来获得name值的多个对应值。少数情况下,当你需要raw
request的适合,可以使用getReader和getInputStream。
     但是我们可以发现,直接对httpServletRequest的parameter进行set操作会报错,因此需要使用HttpServletRequestWrapper。HttpServletRequestWrapper允许我们重写servletRequest的各种方法,以便对request进行直接操作。
     因此,我们可以在自定义的RequestWrapper中,对getParameter和getParameterValues进行重写,从而达到对各个用户输入的form参数的值进行过滤,滤掉form data中的恶意脚本。以下为示例代码:
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] = xssClean(values[i]);
        }
        return encodedValues;
    }

public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (value == null) {
            return null;
        }
        return xssClean(value);
    }

2. 在输入流中检测滤掉来自其他网站的URL中的恶意脚本
     当用户不小心点击了被其他黑客提供的假冒URL,则可能在该URL中注入恶意脚本。因此,也需要对这种情况进行处理。因此为确保其他在header中的恶意脚本,需要对request.getHeader进行重写。以下为例子:
public String getHeader(String name) {
        String value = super.getHeader(name);
        if (value == null)
            return null;
        return xssClean(value);

}

3. xssClean函数怎样实现才可以过滤掉恶意脚本呢?
如果是java语言,推荐使用antisamy。使用antisamy进行XSS清理非常简单,只需要简单的几个步骤即可达到目的。
     1‘. 在pom.xml文件中加入antisamy的dependency,
     <dependency>
            <groupId>org.owasp.antisamy</groupId>
            <artifactId>antisamy</artifactId>
            <version>1.5.3</version>
        </dependency>
     2’.

加入了dependency之后,就可以在xssClean中加入antisamy对恶意脚本进行清理。其中policy.xml是白名单,policy.xml中规定了各个html元素所必须满足的条件。antisamy的精髓之处在于,使用policy文件来规定你的过滤条件,若输入字符串不满足policy文件中的条件,则会过滤掉字符中的恶意脚本,返回过滤后的结果。具体代码如下:
private String xssClean(String value) {
        AntiSamy antiSamy = new AntiSamy();
        try {
            final CleanResults cr = antiSamy.scan(value, Policy.getInstance("policy.xml"), AntiSamy.SAX);
            return cr.getCleanHTML();
        } catch (ScanException e) {
            e.printStackTrace();
        } catch (PolicyException e) {
            e.printStackTrace();
        }
        return value;
    }
这样,我们就将client端用户输入的request,在server端进行了拦截,并且进行了过滤。对于输出端,XSS的防御将在下一篇文章中进行详细介绍。
转载请注明出处,谢谢。

怎样过滤跨站恶意脚本攻击(XSS)的更多相关文章

  1. CSRF跨站请求伪造与XSS跨域脚本攻击讨论

    今天和朋友讨论网站安全问题,聊到了csrf和xss,刚开始对两者不是神明白,经过查阅与讨论,整理了如下资料,与大家分享. CSRF(Cross-site request forgery):跨站请求伪造 ...

  2. XSS跨站脚本攻击与CSRF跨站请求伪造攻击的学习总结(转载)

    转载自 https://blog.csdn.net/baidu_24024601/article/details/51957270 之前就了解过这方面的知识,但是没有系统地总结.今天在这总结一下,也让 ...

  3. SpringSecurity原理解析以及CSRF跨站请求伪造攻击

    SpringSecurity SpringSecurity是一个基于Spring开发的非常强大的权限验证框架,其核心功能包括: 认证 (用户登录) 授权 (此用户能够做哪些事情) 攻击防护 (防止伪造 ...

  4. 教你轻松解决CSRF跨站请求伪造攻击

    摘要:CSRF(Cross-site request forgery)跨站请求伪造,通过伪装来自受信任用户的请求来利用受信任的网站.与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也 ...

  5. 安全性测试入门 (三):CSRF 跨站请求伪造攻击和防御

    本篇继续对于安全性测试话题,结合DVWA进行研习. CSRF(Cross-site request forgery):跨站请求伪造 1. 跨站请求伪造攻击 CSRF则通过伪装成受信任用户的请求来利用受 ...

  6. (28)django的中间件(自定义中间件和防范跨站请求伪造攻击)-重要的概念

    Django中间件和中间件不是同一种东西 什么是中间件:中间件是一个很大的概念,只要程序和程序之间还有一层程序,用来处理两个程序的整个交互过程的请求.数据等等就叫中间件 Django中间件:是介于re ...

  7. (22)Ajax的基本使用(实现登录功能和局部刷新以及防止跨站请求伪造攻击)

    Ajax的作用 前后端分离的项目,需要交互,就要通过Ajax来完成交互 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即 ...

  8. ASP.NET Core中的OWASP Top 10 十大风险-跨站点脚本攻击 (XSS)

    不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: https://dotnetcoretutorials.com/201 ...

  9. 跨站点脚本攻击XSS

    来源:http://www.freebuf.com/articles/web/15188.html 跨站点脚本攻击是一种Web应用程序的攻击,攻击者尝试注入恶意脚本代码到受信任的网站上执行恶意操作.在 ...

随机推荐

  1. cbuffer padding

    nx glslc float 起始于 内存位置4x0 ,4x1,4x2 ,4x3.... bit float2 起始于 内存位置2x4x0 ,2x4x1,2x4x2 ,2x4x3.... bit fl ...

  2. linux /boot目录下的文件分析

    一. Linux 启动流程 首先说一下Linux系统大概的启动过程: 1. 主机加电后, 系统首先加载BIOS, 这个BIOS是以写在主板上的. 2. BIOS启动后,执行一些例如开机自检,硬件初始化 ...

  3. Keepalived高可用集群应用

    Keepalived高可用集群应用 1.keepalived服务说明 1.1.keepalived介绍 Keepalived是一个用C语言编写的路由软件.该项目的主要目标是为Linux系统和基于Lin ...

  4. Solidworks 好的测试题模拟题

    题目:按照下图构建草图,注意设置必要的几何约束. 问题:   1.参照下图所示参数时请问其中绿色区域的面积为多少平方毫米?     题目:参照下图绘制草图轮廓,注意图中各线条之间均为相切过渡. 问题: ...

  5. Android学习(十三) BroadcastReceiver组件(广播)

    一.Broadcast(广播) 是一种广泛应用在应用程序之间传输信息的机制. 二.Broadcast(广播接收器) 是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播 ...

  6. Laravel之Eloquent ORM关联

    一.一对一 1.主对从(hasOne) 从User模型中取出用户的手机 User模型中: /** * 获取关联到用户的手机 */ public function phone() { return $t ...

  7. Laravel之HTTP相应

    一.基本相应示例 1.返回简单字符串 Route::get('/', function () { return 'Hello World'; }); 给定的字符串会被框架自动转化为 HTTP 响应 2 ...

  8. spring 源码下载

    github spring 源码 导入Spring源码方法 java世界中的三大构建工具:ant,maven,gradle gradle 简介

  9. 基于Django进行简单的微信开发

    代码地址如下:http://www.demodashi.com/demo/11756.html 一.微信公众号的准备: 1. 注册 访问地址:https://mp.weixin.qq.com/ 按照提 ...

  10. Install RabbitMQ server in CentOS 7

    About RabbitMQ RabbitMQ is an open source message broker software, also sometimes known as message-o ...