网络安全必学知识点之 XSS 漏洞
xss 漏洞小结
一、初识 XSS
1、什么是 XSS
XSS 全称跨站脚本(Cross Site Scripting),为避免与层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为 XSS。这是一种将任意 Javascript 代码插入到其他 Web 用户页面里执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能,在 HTML 页面里嵌入恶意代码。当用户浏览改页时,这些潜入在 HTML 中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的,如 cookie 窃取等。
2、XSS 产生原因、漏洞原理
形成 XSS 漏洞的主要原因是程序对输入和输出的控制不够严格,导致“精心构造”的脚本输入后,在输到前端时被浏览器当作有效代码解析执行从而产生危害。
2021最新整理网络安全/渗透测试/安全学习/100份src技术文档(全套视频、大厂面经、精品手册、必备工具包、路线)一>获取<一
3、XSS 会造成那些危害?
攻击者通过 Web 应用程序发送恶意代码,一般以浏览器脚本的形式发送给不同的终端用户。当一个 Web 程序的用户输入点没有进行校验和编码,将很容易的导致 XSS。
1、网络钓鱼,包括获取各类用户账号 2、窃取用户 cookies 资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作;3、劫持用户(浏览器)会话,从而执行任意操作,例如非法转账、强制发表日志、电子邮件等 4、强制弹出广告页面、刷流量等 5、网页挂马;6、进行恶意操作,如任意篡改页面信息、删除文章等 7、进行大量的客户端攻击,如 ddos 等 8、获取客户端信息,如用户的浏览历史、真实 p、开放端口等 9、控制受害者机器向其他网站发起攻击;10、结合其他漏洞,如 csrf,实施进步危害;11、提升用户权限,包括进一步渗透网站 12、传播跨站脚本蠕虫等
4、XSS 的防御
形成 XSS 漏洞的主要原因是程序对输入和输出的控制不够严格,导致“精心构造”的脚本输入后,在输到前端时被浏览器当作有效代码解析执行从而产生危害。
因此在 XSS 漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理: 输入过滤:对输入进行过滤,不允许可能导致 XSS 攻击的字符输入; 输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
5、XSS 常见出现的地方
1、数据交互的地方
get、post、cookies、headers
反馈与浏览
富文本编辑器
各类标签插入和自定义
2、数据输出的地方
用户资料
关键词、标签、说明
文件上传
6、XSS 的分类
反射性 XSS
又称非持久型 XSS,这种攻击方式往往具有一次性,只在用户单击时触发。跨站代码一般存在链接中,当受害者请求这样的链接时,跨站代码经过服务端反射回来,这类跨站的代码通常不存储服务端
常见注入点:网站的搜索栏、用户登录入口、输入表单等地方,常用来窃取客户端 cookies 或钓鱼欺骗。
漏洞产生原因一般是网站只是简单地将用户输入的数据直接或未经过完善的安全过滤就在浏览器中进行输岀,导致输岀的欻据中存在可被浏览器执行的代码数据
攻击方式攻击者通过电子邮件等方式将包含 XSS 代码的恶意链接发送给目标用户。当目标用户访问该链接时,服务器接受该目标用户的请求并进行处理,然后服务器把带有 XSS 的代码发送给目标用户的浏览器,浏览器解析这段带有 XSS 代码的恶意脚本后,就会触发 XSS 漏洞。由于此种类型的跨站代码存在于 URL 中,所以黑客通常需要通过诱骗或加密变形等方式将存在恶意代码的链接发给用户,只有用户点击以后才能使得攻击成功实施。
反射型 XSS 攻击的流程如下:1.攻击者寻找具有漏洞的网站 2.攻击者给用户发了一个带有恶意字符串的链接 3.用户点击了该链接 4.服务器返回 HTML 文档,此时该文档已经包含了那个恶意字符串 5.客户端执行了植入的恶意脚本,XSS 攻击就发生
存储型 XSS
存储型 XSS( Stored xss Attacks),也是持久型 XSS,比反射型 XSS 更具有威胁性。。攻击脚本将被永久的存放在目标服务器的数据库或文件中。这是利用起来最方便的跨站类型,跨站代码存储于服务端(比如数据库中)
常见注入点论坛、博客、留言板、网站的留言、评论、日志等交互处。</pre>
造成漏洞原因一般是由于 Web 应用程序对用户输入数据的不严格,导致 Web 应用程序将黑客输入的恶意跨站攻击数据信息保存在服务端的数据库或其他文件形式中。
攻击方式攻击者在发帖或留言的过程中,将恶意脚本连同正常信息一起注入到发布内容中。随着发布内容被服务器存储下来,恶意脚本也将永久的存放到服务器的后端存储器中。当其他用户浏览这个被注入了恶意脚本的帖子时,恶意脚本就会在用户的浏览器中得到执行。
存储型ⅩSS 攻击的流程如下 1.用户提交了一条包含 XSS 代码的留言到数据库 2.当目标用户查询留言时,那些留言的内容会从服务器解析之后加载出来 3.浏览器发现有 XSS 代码,就当做正常的 HTML 和 JS 解析执行
DOM 型 XSS
DoM 是文档对象模型( Document Object Model)的缩写。它是 HTML 文档的对象表示,同时也是外部内容(例如 JavaScript)与 HTML 元素之间的接口。解析树的根节点是“ Document"对象。DOM( Document object model),使用 DOM 能够使程序和脚本能够动态访问和更新文档的内容、结构和样式。
它是基于 DoM 文档对象的一种漏洞,并且 DOM 型 XSS 是基于 JS 上的,并不需要与服务器进行交互。
其通过修改页面 DOM 节点数据信息而形成的ⅩSS 跨站脚本攻击。不同于反射型 XSS 和存储型 XSS,基于 DOM 的 XSS 跨站脚本攻击往往需要针对具体的 Javascript DOM 代码进行分析,并根据实际情况进行 XSS 跨站脚本攻击的利用。
一种基于 DOM 的跨站,这是客户端脚本本身解析不正确导致的安全问题
注入点通过 js 脚本对对文档对象进行编辑,从而修改页面的元素。也就是说,客户端的脚本程序可以 DOM 动态修改页面的内容,从客户端获取 DOM 中的数据并在本地执行。由于 DOM 是在客户端修改节点的,所以基于 DOM 型的 XSS 漏洞不需要与服务器端交互,它只发生在客户端处理数据的阶段。
攻击方式用户请求一个经过专门设计的 URL,它由攻击者提供,而且其中包含 XSS 代码。服务器的响应不会以任何形式包含攻击者的脚本,当用户的浏览器处理这个响应时,DOM 对象就会处理 XSS 代码,导致存在 XSS 漏洞。
它的流程是这样的:1.攻击者寻找具有漏洞的网站 2.攻击者给用户发了一个带有恶意字符串的链接 3.用户点击了该链接 4.服务器返回 HTML 文档,但是该文档此时不包含那个恶意字符串 5.客户端执行了该 HTML 文档里的脚本,然后把恶意脚本植入了页面 6.客服端执行了植入的恶意脚本,XSS 攻击就发生了
反射型 XSS 与 DOM 型区别:
1、反射型 XSS 攻击中,服务器在返回 HTML 文档的时候,就已经包含了恶意的脚本;
2、DOM 型ⅩSS 攻击中,服务器在返回 HTML 文档的时候,是不包含恶意脚本的;恶意脚本是在其执行了非恶意脚本后,被注入到文档里的
通过 JS 脚本对对文档对象进行编辑,从而修改页面的元素。也就是说,客户端的脚本程序可以 DOM 动态修改页面的内容,从客户端获取 DOM 中的数据并在本地执行。由于 DOM 是在客户端修改节点的,所以基于 DOM 型的 XSS 漏洞不需要与服务器端交互,它只发生在客户端处理数据的阶段。
其他类型的 XSS
MXSS
不论是服务器端或客户端的ⅩSS 过滤器,都认定过滤后的 HTM 源代码应该与浏览器所渲染后的 HTML 代码保持一致,至少不会出现很大的出入
然而,如果用户所提供的富文本内容通过 Javascript 代码进属性后,一些意外的变化会使得这个认定不再成立:一串看似没有任何危害的 HTML 代码,将逃过 XSS 过滤器的检测,最终进入某个 DOM 节点中,浏览器的渲染引擎会将本来没有任何危害的 HTML 代码渲染成具有潜在危险的 XSS 攻击代码。 随后,该段攻击代码,可能会被 JS 代码中的其它一些流程输出到 DOM 中或是其它方式被再次渲染,从而导致 XSS 的执行。这种由于 HTML 内容进后发生意外变化( mutation,突变,来自遗传学的一个单词,大家都知道的基因突变,gene mutation),而最终导致 XS 的攻击流程,被称为突变 XSS(mXSs, Mutation based Cross-Site-Scripting
通常通过 innerHTML 函数进行 html 代码过滤
什么是 HTML 过滤器?为什么我们需要 HTML 过滤器?
许多 web 应用程序,以编辑器的形式,允许用户使用一些特殊的文本格式(例如,粗体,斜体等等)。这个功能在博客,邮件当中使用甚广。这里出现的主要安全问题就是有些不法用户可能输入一些恶意 HTML/ avaScript 从而引入 XSS。 因此,这类允许用户进行个性化输入的应用程序的创建者就面临一个很头疼的问题如何确保用户的输入的 HTML 是安全的,从而不会引起不必要的 XSS。 这就是为什么需要 HTML 过滤器的原因。HTML 过滤器的主要目的是揪出不可信的输入,对其进行过滤,并生成安全的 HTML 过滤所有危险标签的 HTML
举个例子
解析后,输入的 html 代码变成下面格式
通过 html 过滤器,过滤不在白名单的代码,得到如下无害 html 代码,也不会伤害到用户的正常功能
虽然 HTML 过滤器可以帮助我们处理大部分数据,能够处理 99%的威胁,但是最后一公里路还是要有浏览器来渲染加载。 我们看一个简单的例子:
上面代码一开始并没有闭合的标签,通过渲染后自动加入闭合标签。
在赋值给 innerHTML 之后,我们却得到一个不同的值。由于 HTML/XML 格式的灵活性,用户可以输入非规范的 HTML,修复成规范的 HTML 就是浏览器的责任了。
道理我都懂,但是有没有更直观的例子?
首先分配一个<sg>
标签,<p>
是它的子标签。但是从 DOM 树中我们可以发现,<p>
元素实际上“跳出”了<svg>
。发生这种情况的主要原因是<p>
不是<sg>
中的有效标签,因此浏览器会在结束<SVg>
后打开<p>
UXSS
UXSS 全称 Universal Cross-Site Scripting,翻译过来就是通用型 XSS,也叫 Universal XSS。UXSS 保留了基本 XSS 的特点,利用漏洞,执行恶意代码,但是有一个重要的区别:不同于常见的 XSS,UXSS 是一种利用浏览器或者浏览器扩展漏洞来制造产生 XSS 的条件并执行代码的一种攻击类型。
俗的说,就是原来我们进行 XSS 攻击等都是针对 Web 应用本身,是因为 Web 应用本身存在漏洞才能被我们利用攻击;而 UXSS 不同的是通过浏览器或者浏览器扩展的漏洞来”制作ⅩSS 漏洞”,然后剩下的我们就可以像普通 XSS 那样利用攻击了。
不同于常见的 XSS,UXSS 是一种利用浏览器或者浏览器扩展漏洞来制造产生 XSS 的条件并执行代码的一种攻击类型。UXSS 是一种利用浏览器或者浏览器扩展漏洞来制造产生 XSS 的条件并执行代码的一种攻击类型。UXSS 可以理解为 Bypass 同源策略。
常见的 XSS 攻击的是因为客户端或服务端的代码开发不严谨等问题而存在漏洞的目标网站或者应用程序。这些攻击的先决条件是页面存在漏洞, 而它们的影响往往也围绕着漏洞页面本身的用户会话。换句话说,因为浏览器的安全功能的影响,XSS 攻击只能读取受感染的会话,而无法读取其他的会话信息,也就是同源策略的影响。
1.IE8 跨站脚本过滤器缺陷
David Lindsay 和 Eduardo vela Nava 已经在 2010 年的 BlackHat Europe 展示了这个漏洞的 UXSS 利用。 IE8 中内置了 XSS 过滤器,用于检测反射 XSS 并采取纠正措施:在页面渲染之前更改响应内容。在这种特殊情况下,等号将会被过滤器去除,但是通过精心构造的 XSS 字符串在特定的地方,这个逻辑会导致浏览器创建 XSS 条件。 微软的响应是改变了 XSS 过滤器去除的字符。
2.IE8 跨站脚本过滤器缺陷
移动设备也不例外,而且可以成为 XSS 攻击的目标。 Chrome 安卓版存在一个漏洞,允许攻击者将恶意代码注入到 Chrome 通过 Intent 对象加载的任意的 Web 页面
3.安卓浏览器 SOP 绕过漏洞
限制于特定的安卓系统版本,因为 kitkat( android 4.4)之前 webview 组件使用 webview 内核而遗留的漏洞。该漏洞可以通过构造一个页面,页面嵌入 iframe ,然后通过\u0000 进行浏览器的 sop 绕过进行 XSS
那么 UXSS 与通常的 XSS 有什么影响的区别?
因为一些安全策略,即使一个漏洞页面存在 XSS,我们可以访问它的用户会话信息等但是无法访问其他域的相关的会话信息,而因为 UXSS 是利用浏览器本身或者浏览器扩展程序的漏洞,所以对于攻击发起时浏览器打开或缓存的所有页面(即使不同域的情况)的会话信息都可以进行访问。简单的说,∪XSS 不需要—个漏洞页面来触发攻击,它可以渗透入安全没有问题的页面,从而创造一个漏洞,而该页面原先是安全无漏洞的。 不仅是浏览器本身的漏洞,现在主流浏览器都支持扩展程序的安装,而众多的浏览器扩展程序可能导致带来更多的漏洞和安全问题。 因为 UXSS 攻击不需要页面本身存在漏洞,同时可能访问其他安全无漏洞页面,使得 UXSS 成为 XSS 里危险和最具破坏性的攻击类型之一
七、常见标签
<img>
标签
利用方式 1
<imgsrc=javascript:alert("xss")>
<IMGSRC=javascript:alert(String.formCharCode(88,83,83))>
<imgscr="URL"style='Xss:expression(alert(/xss));'
imgSTYLE="background-image:url(javascript:alert('XSS'))"
XSS 利用方式 2
<imgsrc="x"onerror=alert(1)>
<imgsrc="1"onerror=eval("alert('xss')")>
XSS 利用方式 3
<imgsrc=1onmouseover=alert('xss')>
<a>
标签
标准格式
<ahref="https://www.baidu.com">baidu</a>
XSS 利用方式 1
<ahref="javascript:alert('xss')">aa</a>
<ahref=javascript:eval(alert('xss'))>aa</a>
<ahref="javascript:aaa"onmouseover="alert(/xss/)">aa</a>
XSS 利用方式 2
<script>alert('xss')</script>
利用方式 3
<ahref=""onclick=eval(alert('xss'))>aa</a>
利用方式 4
<ahref=kycg.asp?ttt=1000onmouseover=prompt('xss')y=2016>aa</a>
input 标签
标准格式
<inputname="name"value="">
利用方式 1
<inputvalue=""onclick=alert('xss')type="text">
利用方式 2
<inputname="name"value=""onmouseover=prompt('xss')bad="">
利用方式 4
<inputname="name"value=""><script>alert('xss')</script>
<form>
标签
XSS 利用方式 1
<formaction=javascript:alert('xss')method="get">
<formaction=javascript:alert('xss')>
XSS 利用方式 2
<formmethod=postaction=aa.asp?onmouseover=prompt('xss')>
<formmethod=postaction=aa.asp?onmouseover=alert('xss')>
<formaction=1onmouseover=alert('xss)>
XSS 利用方式 3
<formmethod=postaction="data:text/html;base64,<script>alert('xss')</script>">
<formmethod=postaction="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<iframe>
标签
XSS 利用方式 1
<iframesrc=javascript:alert('xss');height=5width=1000/><iframe>
XSS 利用方式 2
<iframesrc="data:text/html,<script>alert('xss')</script>"></iframe>
<iframesrc="data:text/html;base64,<script>alert('xss')</script>">
<iframesrc="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
XSS 利用方式 3
<iframesrc="aaa"onmouseover=alert('xss')/><iframe>
XSS 利用方式 3
<iframesrc="javascript:prompt(
xss)"></iframe>
svg<>
标签
<svgonload=alert(1)>
二、session 与 cookie
session
由于 HTTP 协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是 Session
典型的场景比如购物车,当你点击下单按钮时,由于 HTTP 协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的 Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。
这个 Session 是保存在服务端的,有一个唯一标识。在服务端保存 Session 的方法很多,内存、数据库、文件都有。集群的时候也要考虑 Session 的转移,在大型的网站一般会有专门的 Session 服务器集群,用来保存用户会话,这个时候 Session 信息都是放在内存的,使用一些缓存服务比如 Memcached 之类的来放 Session。
cookie
思考一下服务端如何识别特定的客户?这个时候 Cookie 就登场了。
每次 HTTP 请求的时候,客户端都会发送相应的 Cookie 信息到服务端。实际上大多数的应用都是用 Cookie 来实现 Session 跟踪的,第一次创建 Session 的时候,服务端会在 HTTP 协议中告诉客户端,需要在 Cookie 里面记录个 SessionID,以后每次请求把这个会话 ID 发送到服务器,我就知道你是谁了。
设想你某次登陆过一个网站,只需要登录一次就可以在一定时间内浏览这个网站的所有内容,这是如何做到的?也是 Cookie
Cookie 是指某些网站为了辨别用户身份而储存在客户端上的数据(通常经过加密)。也就是说,只要有了某个用户的 cookie,就能以他的身份登录
获取 cookie:
浏览器(客户端):document.cookie
服务器端(php):$_COOKIE
举例
知道了 cookie 的格式, cookie 的属性选项,接下来我们就可以设置 cookie 了。首先得明确一点:cookie 既可以由服务端来设置,也可以由客户端来设置。
1、一个 Set-Cookie 字段只能设置一个 cookie,当你要想设置多个 cookie,需要添加同样多的 Set- Cookie 字段。 2、服务端可以设置 cookie 的所有选项:expires、 domain、path、 secure、 HttpOnly
客户端可以设置 cookie 的下列选项:expires、 domain、path、 secure(有条件:只有在 https 协议的网页中,客户端设置 secure 类型的 cookie 才能成功),但无法设置 HttpOnly 选项。
三、浏览器解析方式
语言的解析般分为词法分析( lexical analysis)和语法分析( Syntax analysis)两个阶段, Webkit 中的 HTML 解析也不例外,我们这里主要关注词法分析。
词法分析的任务是对输入字节流进行逐字扫描,根据构词规则识别单词和符号,分在 WebKⅰt 中,有两个类,同词法分析密切相关,它是 HTMLToken 和 HTMLTokenizer 类,可以简单将 HTMLToken 类理解为标记, HTMLTokenizer 类理解为词法解析器。HTML 词法解析的任务,就是将输入的字节流解析成一个个的标记( HTMLToken),然后由语法解析器进行下一步的分析
在 XML/HTML 的文档解析中, token 这个词经常用到,我将其理解为一个有完整语义的单元(也就是分出来的“词”),一个元素通常对应于 3 个 token,一个是元素的起始标签,一个是元素的结束标签,一个是元素的内容,这点同 DOM 树是不一样的,在 DOM 树上,起始标签和结束标签对应于一个元素节点,而元素内容对应另一个节点。
除了起始标签( StartTag)、结束标签(仼 drAg)和元素内容( Character),HTM 标签还有 DOCTYPE(文档类型) Comment(注释), Uninitialized(默认类型)和 EndofFile(文档结束)等类型,参见 HTMLToken h 中的 Type 枚举。
在 HTML 中,某些字符是预留的。例如在 HTML 中不能使用<
或>
,这是因为浏览器可能误认为它们是标签的开始或结束。如果希望正确地显示预留字符,就需要在 HTML 中使用对应的字符实体。一个 HTML 字符实体描述如下
字符显示 描述 实体名称 实体编号
< 小于号 <<
需要注意的是,某些字符没有实体名称,但可以有实体编号
HTML 的词法分析:http://www.w3.org/TR/html5/tokenization.html
HTML 的规范是相当宽松的,所以词法解析要考虑到的问题很多,HTML5 specification 在这方面为实现者做了绝大部分工作。 不考虑类似<html>
和<body>
之间的回车换行
......
四、XSS 总结与拓展
(1)输入在标签间的情况:测试<>
是否被过滤或转义,若无则直接<mgsc=1 onerror=alert(1)>
(2)输入在 script 标签内:我们需要在保证内部 JS 语法正确的前提下,去插入我们的 payload。如果我们的输岀在字符串内部,测试字符串能否被闭合。如果我们无法闭合包裹字符串的引号,这个点就很难利用了
可能的解决方案:可以控制两处输入且\
可用、存在宽字节
(3)输入在 HTML 属性內:首先査看属性是否有双引号包裏、没有则直接添加新的事件属性;
有双引号包裹则测试双引号是否可用,可用则闭合属性之后添加新的事件属性;
TIP:HTML 的属性,如果被进行 HTML 实体编码(形如';'
),那么 HTML 会对其进行自动解码,从而我们可以在属性里以 HTML 实体编码的方式引入任意字符,从而方便我们在事件属性里以 JS 的方式构造 payload。
(4)输岀在 JS 中,空格被过滤:使用/**/
代替空格。 (5)输出在 JS 注释中:设法插入换行符%0A
,使其逃逸出来。 (6)输入在 JS 字符串内:可以利用 JS 的十六进制、八进制、 unicode 编码。 (7)输入在src/ href /action
等属性内:可以利用 javascript:alert(1),以及data:text/html;base64;
加上 base64 编码后的 HTML
(8) Chrome 下 iframe 自身的弹框姿势
<iframe onload="alert(1)"></iframe>``<iframe src="javascript:alert(2)"></iframe>``<iframe src=data text/html, <script>alert(3)</script>></iframe>``<iframe srcdoc="<script>alert(4))</script>"></iframe>
(9)坑点之自带 HtmlEncode(转义)功能的标签
<textarea>k/textarea>``<title></title>``<iframe ></iframe>``<noscript></noscript>``<noframes></noframes>``<xmp></xmp>``<plaintext></plaintext>
当我们的 XSS payload 位于这些标签中间时,并不会解析,除非我们把它们闭合掉。
五、CSRF 配合 XSS
CSRF( Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/ session riding,缩写为:CSRF/XSRF。 可以这么理解 CSRF 攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF 能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的问题包括:个人隐私泄露以及财产安全。 如果站点的管理员遭受 CSRF 攻击,在知道相关请求参数的情况下,攻击者可以借助管理员的权限来完成一些操作,如添加账户、上传文件等。 从而,在一些公共系统(如购物网站等)和一些开源系统当中,CSRF 的危害较大;在闭源系统中,单纯的 CSRF 危害较小;不过这也是相对的,CSRF 可以和 XSS 配合使用,从而实现较大的破坏。一旦利用成功,CSRF 同样可以进后台、 getshell
例 1
从上图可以看出,要完成一次 CSRF 攻击,受害者必须依次完成两个步骤 1.登录受信任网站 A,并在本地生成 Cookie。2.在不登出 A 的情况下,访问危险网站 B。 看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到 CSRF 的攻击”。
是的,确实如此,但你不能保证以下情况不会发生:1.你不能保证你登录了一个网站后,不再打开—个 tab 页面并访问另外的网站。2.你不能保证你关闭浏览器了后,你本地的 Cookie 立刻过期,你上次的会话已经结束。(事实上,关闭浏览器并不能一定结束一个会话,但有些人都会错误的认为关闭浏览器就等于退出登录结束会话了…3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
例 2
银行网站 A,它以 GET 请求来完成银行转账的操作,如: http://www.mybank.com/transfer.php?tobankid=1l&money=1000存在一个危险网站 B,它里面有一段 HTML 的代码如下
<img src=http://www.mybank.com/transferphp?tobankld=11&moneY=1000>
首先,你登录了银行网站 A,然后访问危险网站 B,噢,这时你会发现你的银行账户少了 1000 块,为什么会这样呢?
原因是银行网站 A 违反了 HTTP 规范,使用 GET 请求更新资源。在访问危险网站 B 的之前,你已经登录了银行网站 A,而 B 中的<mg>
以 GET 的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站 A 的 Cookie 发出 GET 请求,去获取资源"http://www.mybank.com/transfer.pHp?tobankid=11&money=1000"
,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作.....
六、域、同源、CORS、 JSONP
同源
1995 年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。最初,它的含义是指,A 网页设置的 Cookis,B 网页不能打开,除非这两个网页"同源"
所谓“同源”指的是“三个相同”:
协议相同
域名相同
端口相同
看看示例来小试牛刀
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A 网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取 A 网站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是 Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,"同源政策"是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
随着互联网的发展,"同源政策" 越来越严格。目前,如果非同源,共有三种行为受到限制。
(1)Cookie、 LocalStorage 和 IndexDB 无法读取。(2)DOM 无法获得。(3)AJAX 请求不能发送。
当然,这些条件都是相对的,在某些特殊的情况下,我们也可以通过同源策略所允许的共享机制,完成非同源页面之间数据的传送。
跨域
所谓跨域,或者异源,是指主机名(域名)、协议、端口号 只要有其一不同,就为不同的域(或源)。浏览器中有一个基本的策略,叫同源策略,即限制"源"自 A 的脚本只能操作“同源”页面的 DOM。 浏览器中,< script>/<img>/< iframe>/<link>
等标签都是可以跨域来加载资源的而不受同源策略的影响。带″src′属性的标签每次加载时,实际上都是浏览器发起次”GET”请求。
对于 XMLHttpRequest 来说,它可以访问来自同源对象的内容。但是不能够跨域访问资源。他需要通过目标域返回的 HTTP 头授权是否允许跨域访问,因为 HTTP 头对于 javascript 来说一般是无法控制的,所以认为这个方案是可行的。
对于浏览器来说:除了 DOM、Cookie、XMLTttpRequest 会受到同源策略的限制外,浏览器加载的第三方插件也有各自的同源策略。例如:flash,java applet, silverlight, coogle gears 等。
跨域的方法
JSONP
JSONP 跨城
JSONP 劫持
(1)用户在网站 B 注册并登录,网站 B 包含了用户的 d,name,emai 等信息
(2)用户通过浏览器向网站 A 发出 URL 请求
(3)网站 A 向用户返回响应页面,响应页面中注册了 JavaScript 的回调函数和向网站 B 请求的 script 标签,示例代码如下`
(4)用户收到响应,解析 JS 代码,将回调函数作为参数向网站 B 发岀请求; (5)网站 B 接收到请求后,解析请求的 URL,以 SON 格式生成请求需要的数据,将封装的包含用户信息的 JSON 数据作为回调函数的参数返回给浏览器,网站 B 返回的数据实例如下:Callback(){id":l,"name":test","email":testatest com"})
(6)网站 B 数据返回后,浏览器则自动执行 Callback 函数对步骤 4 返回的 JSON 格式数据进行处理,通过 alert 弹窗展示了用户在网站 B 的注册信息。另外也可将 JSON 数据回传到网站 A 的服务器,这样网站 A 利用网站 B 的 JSONP 漏洞便获取到了用户在网站 B 注册的信息。
CORS
CORS 是一个 W3C 标准,全称是"跨域资源共享"”( Cross-origin resource sharing)
它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。 CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10。
浏览器端:
目前,所有浏览器都支持该功能(IE10 以下不行)。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。
服务端:
CORS 通信与 AJAX 没有任何差别,因此你不需要改变以前的业务逻辑。只不过,浏览器会在请求中携带一些头信息,我们需要以此判断是否运行其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。
不符合简单请求的条件,会被浏览器判定为特殊请求,例如请求方式为 PUT
特殊请求会在正式通信之前,增加一次 HTTP 查询请求,称为"预检"请求( preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。
与简单请求相比,除了 Origin 以外,多了两个头
Access-Control-Request-Method:接下来会用到的请求方式,比如 PUT
Access- Control- Request-Headers:会额外用到的头信息
服务的收到预检请求,如果许可跨域,会发出响应
除了 Access-Contro-Allow-Origin 和 Aces-Contro-Allow-Credentials 以外,这里又额外多出 3 个头:
Access-Contro|-Allow-Methods:允许访问的方式
Access-Control- Allow- Headers:允许携带的头
Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的 ajax 请求就无需再次进行预检了
如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的
PostMessage 跨城
SameSite
Chrome51 开始,浏览器的 Cookie 新增加了—个 SameSite 属性,用来防止 CSRF 攻击和用户追踪。
Cookie 的 Samesite 属性用来限制第三方 Cookie,从而减少安全风险。它可以设置个值 Strict 、 Lax、 None
Strict 最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标—致,才会带上 Cookie。
Set-Cookie:CookieName=CookieValue:SameSite=Strict;
这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 GitHub 链接,用户点击跳转就不会带有 GitHub 的 Cookie,跳转过去总是未登陆状态。
Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
Set-Cookie:CookieName=CookieValue;SameSite=Lax
导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。详见下表。
Chrome 计划将 Lax 变为默认设置。这时,网站可以选择显式关闭 SameSite 属性将其设为 None。不过,前提是必须同时设置 Secure 属性( Cookie 只能通过 Https 协议发送),否则无效。
下面的设置无效:
Set-Cookie:widget_session=abc123;SameSite=None
下面的设置有效:
Set-Cookie:widget_session=abc123;SameSite=None;Secure
七、CSP
CSP 全称为 Content Security Policy,即内容安全策略。主要以白名单的形式配置可信任的内容来源,在网页中,能够使白名单中的内容正常执行(包含 JS,CSS,Image 等等),而非白名单的内容无法正常执行,从而减少跨站脚本攻击(XSS),当然,也能够减少运营商劫持的内容注入攻击。
为使 CSP 可用,你需要配置你的网络服务器返回Content-Security-Policy HTTP
头部(有时你会看到一些关于 X-Content-Security-Policy 头部的提法,那是旧版本,你无须再如此指定它)
除此之外,<meta>
元素也可以被用来配置该策略,例如
CSP 旨在减少(注意这里是减少而不是消灭)跨站脚本攻击。CSP 是一种由开发者定义的安全性政策性申明,通过 CSP 所约束的的规责指定可信的内容来源(这里的内容可以指脚本、图片、 iframe、font、 style 等等可能的远程的资源)。通过 CSP 协定,让 WEB 处于—个相对安全的运行环境中。
无论是反射型/存储型XSS
都因为其 payload 富于变化而难以被彻底根除。
而目前通过对输入输出的检测浏览器自身的 filter 对反射型 XSS 有了一定的检测能力,但是对于存储型 XSS 仍然缺乏一个有效通用解决方案。
内容安全策略(csp)将在未来的 XSS 防御中扮演着日渐重要的角色。 但是由于浏览器的支持,XSS 的环境复杂多变等问题,仍然会存在很多 Bypass 的方法。
八、XS-Leaks
跨站脚本泄漏( Cross-Stie Leaks,又称 XS- Leaks/ XSLeaks),是一类利用 Web 平台内置的侧信道衍生出来的漏洞。其原理是利用网络上的这种侧信道来揭示用户的敏感信息,如用户在其他网络应用中的数据、用户本地环境信息,或者是用户所连接的内部网络信息等。
浏览器提供了各种各样的功能来支持不同 Web 应用程序之间的互动;例如,浏览器允许一个网站加载子资源、导航或向另一个应用程序发送消息。虽然这些行为通常受到网络平台的安全机制的限制(例如同源政策),但 XS- Leaks 利用了网站之间互动过程中的各种行为来泄露用户信息。
既然是侧信道,那么这个信道从何而来呢?通常来说,这个信道需要结合题目设置的各种功能或者浏览器的某些特性,而往往这些功能或者特性对用户的返回只有两种回答,也就是类似 SQL 注入中布尔盲注攻击一样,只不过他放到了浏览器以及 Web 应用当中。举个简单例子,有这么一个搜索功能,对于用户搜索的内容如果存在,则返回 200 码,否则返回其他非 200 状态码响应,我们就可以从头挨个通过 Web 服务返回的状态码来判断自己传递的是否正确进而泄露 Web 服务当中的内容,于是我们还可以使用 onload 等事件进一步进行自动化泄露。再举个小例子,在没有正确设置 SameSite 的情况下,如果存在一些 Web 应用对于用户没有登录返回 403,登录状态返回 200,则可以一些跨域标签,比如 script 可以依照这两种状态来判断用户是否登录。
XS-Leaks 并不是说可以直接造成什么危害巨大的漏洞,它更侧重于 Leak,侧重于信息泄露方面。并且造成大多数 XS-Leaks 的根本原因是网络设计上的问题,很多时候,web 服务在没有漏洞的情况下就容易受到些信息泄露的影响。但是在浏览器层面修复 XS-Leaks 也是及其困难的,因为在许多情况下,会影响到很多现有的 Web 服务,会对原有的 Web 服务造成巨大的冲击。所以,要防御该类型的漏洞,通常是要使用各种严格的同源限制,才能达到预期效果。
九、XSS 编码绕过
js 编码
HTML 实体编码
URL 编码
String.fromCharCode 编码
在线 xss 转码:https://www.toolmao.com/xsstranser
JS 编码
JS 提供了四种字符编码的策略,
三个八进制数字,如果数字不够,在前面补零,如 a 的编码为\141
两个十六进制数字,如果数字不够,在前面补零,如 a 的编码为\x61
四个十六进制数字,如果数字不够,在前面补零,如 a 的编码为\u0061
对于一些控制字符,使用特殊的 C 类型的转义风格,如\n 和\r
HTML 实体编码
命名实体
以 &开头,以分号结尾的,如<的编码为 &1t;
字符编码
十进制,十六进制的 ASCII 码或者 Unicode 字符编码。样式为 &#数值;
如<的编码为
<(10 进制)
<(16 进制)
URL 编码
这里为 url 全编码,也就是两次 url 编码
如 alert 的 url 全编码为 %25%36%31%25%36%63%25%36%35%25%37%32%25%37%34
String.fromCharCode 编码
如 alert 的编码为 String.fromCharCode(97,108,101,114,116)
十、XSS 的防御
使用 XSS Filter
1、输入过滤
输入验证
对用户提交的数据进行有效验证,仅接受指定长度范围内的,采用适当格式的内容提交,阻止或者忽略除此以外的其他任何数据。
常见的检测或过滤:
输入是否仅仅包含合法的字符
输入字符串是否超过最大长度的限制
输入如果为数字,数字是否在指定的范围内
输入是否符合特定的格式要求,如邮箱、电话号码、ip 地址等
2、数据消毒
除了在客户端验证数据的合法性,输入过滤中最重要的还是过滤和净化有害的输入,例如如下常见的敏感字符:
||<> ' "&# javascript expression
2、输出编码
对输出的数据进行编码,如 HTML 编码,就是让可能造成危害的信息变成无害。
白名单和黑名单
定制过滤策略
web 安全编码规范
防御 DOM-Based XSS
两点注意点:
避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务端使用动态页面来实现。
分析和强化客户端 Javascript 代码,尤其是一些受到影响的 Dom 对象
其他防御方式
Anti_XSS
微软开发的,.Net 平台下的,用于方式 XSS 攻击的类库,它提供了大量的编码函数来对用户输入的数据进行编码,可以实现基于白名单的输入的过滤和输出编码。
HttpOnly Cookie
当 Cookie 在消息头中被设置为 HttpOnly 时,这样支持 Cookie 的浏览器将阻止客户端 Javascript 直接访问浏览器中的 cookies,从而达到保护敏感数据的作用。
Noscript
Noscript 是一款免费的开源插件,该插件默认禁止所有脚本,但可以自定义设置允许通过的脚本。
WAF
使用 WAF,比如软 WAF,硬 WAF、云 WAF 等。
评论