3.2 被动攻击与同源策略
本节首先讲述被动攻击这一攻击手法,然后介绍浏览器针对此类攻击的防御策略——沙盒。沙盒技术的核心概念为“同源策略”,它对于理解 Web 应用的安全隐患至关重要,所以,对同源策略这一概念,本节也会进行详细说明。
主动攻击与被动攻击
针对 Web 应用程序的攻击可分为主动攻击(Active Attack)和被动攻击(Passive Attack)。下面先简单介绍这两者的区别,然后再重点讲述被动攻击。
- 主动攻击
所谓主动攻击,是指攻击者直接攻击 Web 服务器。SQL 注入攻击即是主动攻击的代表性例子(图 3-22)。
图 3-22 主动攻击
- 被动攻击
被动攻击是指,攻击者并不直接攻击服务器,而是针对网站的用户设下陷阱,利用掉入陷阱的用户来攻击应用程序。下面,让我们按照由易到难的顺序来依次解说被动攻击的 3 种模式。
- 单纯的被动攻击
将用户诱导至设有圈套的网站,就是一种单纯的被动攻击模式。图 3-23 描绘了此类攻击的流程。
图 3-23 单纯的被动攻击
此类攻击的典型案例为,用户在浏览过所谓的“可疑网站”之后会感染上恶意软件(病毒等)。理论上如果浏览器(包括 Adobe Flash Player 等插件)不存在漏洞,此类单纯的被动攻击是行不通的。但现实中,针对浏览器以及 Adobe Reader、Adobe Flash Player、JRE 等插件的漏洞进行的攻击却层出不穷。
- 单纯的被动攻击
- 恶意利用正规网站进行的被动攻击
下面介绍一种稍微复杂一些的被动攻击模式,即通过在正规网站设置陷阱来实施攻击。这也是一种屡见不鲜的模式。图 3-24 描绘了此类攻击的流程。
图 3-24 在正规网站中设置陷阱的被动攻击
攻击者事先入侵正规网站,往其内容中嵌入恶意代码(①)。网站用户在浏览了含有恶意代码的内容后(②~③),就会感染病毒(④)。在这一流程中,单看步骤①的话似乎应归类为主动攻击,但步骤②~④均为被动攻击,因此,可将①视作被动攻击的前期准备。
通过恶意利用正规网站进行被动攻击,与自己准备一个恶意网站这种单纯的攻击模式相比要费事得多,但另一方面,这种方式对于攻击者来说可以说是利大于弊,原因如下。
- 不需要专门将用户诱导至恶意网站
- 正规网站的用户数量庞大,因此能提高增加受害者的可能性
- 攻击者能入侵正规网站,非正当地使用其功能,并从中受益
- 攻击者能通过窃取网站用户的个人信息而受益
在正规网站中设置陷阱的手法通常有下列 4 种。
- 非法获取 FTP 等服务器的密码后篡改网站内容(参考 7.1 节)
- 通过攻击 Web 服务器的安全隐患来篡改网站内容(参考 7.1 节)
- 通过 SQL 注入攻击来篡改网站内容(参考 4.4 节)
- 在社交网络这类用户能够自己发布内容的网站上,利用跨站脚本漏洞实施攻击(参考 4.3 节)
2010 年初爆发的恶意程序 Gumblar 就属于此类模式的被动攻击。另外,2008 年以来数量急剧增加的 SQL 注入攻击,也被频繁地用于此类攻击。而无论哪种方法,在第 1 章介绍的僵尸网络的构建过程中,都会被恶意使用。
- 跨站被动攻击
最后,让我们看一下同时使用恶意网站和正规网站的被动攻击模式。攻击流程见图 3-25。
图 3-25 跨站被动攻击
接下来,让我们根据上图来看一下跨站被动攻击的具体流程。
① 用户浏览恶意网站
② 从恶意网站下载含有恶意代码的 HTML9
③ HTML 中的恶意代码被触发,从而向正规网站发送攻击请求
④ 正规网站返回含有 JavaScript 等的响应内容
有些情况下步骤④会被省略。
此类攻击的特征为,恶意利用已经在正规网站登录的用户账号来实施攻击。由于步骤③的请求中要向正规网站发送会话 Cookie,因此,如果用户已经在正规网站登录,就会利用其已经登录的状态实施攻击。
此类攻击模式的典型案例包括,在步骤③的请求中对 Web 应用发动攻击的跨站请求伪造(CSRF,参考 4.5 节),以及在步骤④的响应中利用浏览器来执行攻击的跨站脚本攻击(XSS,参考 4.3 节)和 HTTP 消息头注入攻击(参考 4.7 节)。
9 含有恶意代码的 HTML,多是指在网络论坛上发布的专门用来攻击的 URL。
浏览器如何防御被动攻击
针对以上被动攻击,浏览器和网站都需要采取相应的防御措施。本书将从第 4 章开始详述网站方面的对策,但其前提是浏览器不存在安全方面的问题。如果浏览器存在安全问题,网站方面即使实施了对策也无法完全确保安全性。
在说明网站的对策之前,让我们先来关注一下浏览器的安全功能。
- 沙盒
浏览器能够在用户浏览网站的同时运行一些程序,比如 JavaScript、Java Applet、Adobe Flash Player、ActiveX 等。而为了防止恶意程序在用户的浏览器上运行,JavaScript 等语言提供了一些增强安全性的机能。基本思想有如下两种。
- 只有在用户确认了程序的发行方并且允许运行的情况下,程序才能被运行
- 提供限制程序权限的沙盒环境
第一种方式经常被用于 ActiveX 或带有签名的 Applet,但如果一般的应用程序都采用这种方式的话,对用户来说就显得负担过大,因此,现在这种方式主要用于为浏览器提供插件功能。
沙盒(Sandbox),是 JavaScript、Java Applet、Adobe Flash Player 等经常使用的一种思路。在沙盒里面,程序的权限受到制约,即使编写了恶意程序也无法对用户造成伤害。就像孩子们能在沙地中尽情地喧闹而不会给外界带来困扰一样,由此便使用了英语“sandbox”一词,并将其引申为“沙盒”。
通常情况下,沙盒限制了以下功能。
- 禁止访问本地文件
- 禁止使用打印机等资源(可以显示页面)
- 限制网络访问(同源策略)
虽然网络访问无法被完全禁止,但却受到了严格的限制,此限制就被称为同源策略。下面,让我们一起看一下 JavaScript 中的同源策略。
- 同源策略
同源策略(Same Origin Policy)是禁止 JavaScript 进行跨站访问的安全策略。它也是浏览器的沙盒环境所提供的一项制约。
浏览器可以同时处理多个网站的内容,其典型方法为使用标签页或 frame 等。下面,我们以 iframe 为例来说明同源策略的必要性。
- JavaScript 访问 iframe 的试验
接下来,让我们通过观察 JavaScript 对 iframe 的访问限制来体验同源策略。首先,有一点需要了解到的是,如果主机(Host)相同,在 iframe 的外部就能够通过 JavaScript 取得 iframe 内部的 HTML 内容。
下面展示的是包含 iframe 要素的“外层”HTML10 。
代码清单 /32/32-001.html(外层 HTML)
<html> <head><title> 跨 frame 的读取试验 </title></head> <body> ┌在 iframe 中显示其他 HTML 的内容 <iframe name="iframe1" width="300" height="80" src="https://www.wenjiangs.com/wp-content/uploads/2024/10/http://example.jp/32/32-002.html" > </iframe><br> <input type="button" onclick="go()" value=" 密码→ "> <script> function go() { try { ┌───取得 iframe 中的内容 var x = iframe1.document.form1.passwd.value ; document.getElementById('out').innerHTML = x ; } catch (e) { └───在 DOM 中显示读取出的字符串 alert(e.message); } } </script> <span id="out"></span> </body> </html>
下面是显示在 iframe 中的“内层”HTML。
代码清单 /32/32-002.html(内层 HTML)
<body> <form name="form1"> iframe 的内层 <br> 密码 <input type="text" name="passwd" value="password1"> </form> </body>
运行页面如图 3-26 所示。点击“密码→”按钮后,iframe 内部的文本框中的文字出现在了按钮右侧。由此证实了 JavaScript 能够取得 iframe 内部的内容。
图 3-26 JavaScript 能够读取 iframe 内部数据
- iframe 被恶用的可能性
iframe 内部的信息能被 JavaScript 读取,这样会不会有安全性问题呢?
现在假设你是被动攻击的受害者。在 example.jp 登录以后,浏览了恶意网站 trap.example.com。恶意网站使用 iframe 来显示 example.jp 的内容,如图 3-27 所示。由于你已经登录了 example.jp,所以 iframe 内会显示你的个人信息,但这些信息只有你自己看到,所以显示在浏览器上本身不存在问题。
图 3-27 使用 iframe 的恶意网站
但是,假如恶意网站能用 JavaScript 访问 iframe 内部信息的话就存在问题了。因为你的个人 信息会被恶意网站上的脚本发送给它的服务器。下面我们来试验一下这是否可行。
这次充当恶意网站的是包含 iframe 的 HTML(32-900.html),假设它被托管于 trap.example.com, 并在其 iframe 中显示刚才的 32-002.html(内侧 HTML)。32-900.html 虽然扮演恶意网站的角色, 但其内容同 32-001.html 一样。
- 同源策略
访问 http://trap.example.com/32/32-900.html 后点击“密码→”按钮,页面显示如下。
图 3-28 恶意网站试图使用 JavaScript 读取 iframe 内部内容被拒绝
虽然 iframe 内可以显示 example.jp 的内容,但是其他主机(trap.example.com)上的 JavaScript 却无法访问其内容。这是因为 JavaScript 若能访问其他主机的话就会导致安全性问题,所以根据同源策略,访问遭到了拒绝。
- 同源的条件
目前为止一直使用着“相同主机”这个含糊的用语,而严格来说,“同源”需满足以下全部条件。
- URL 的主机(FQDN :Fully Qualified Domain Name,全称域名)一致 11
- Scheme(协议)一致
- 端口号一致
发送 Cookie 时的条件与协议或端口号无关,所以针对 JavaScript 的限制正变得越发严格。而另一方面,JavaScript 却没有访问目录的限制 12 。
同源策略的保护对象不仅仅是 iframe 内的文档。比如,实现 Ajax 时所使用的 XMLHttpRequest 对象能够访问的 URL 也受到了同源策略的限制。
- JavaScript 访问 iframe 的试验
- 应用程序安全隐患与被动攻击
虽然浏览器的同源策略为抵御被动攻击设下了一道屏障,但如果应用程序中存在安全隐患,还是有可能会遭受到被动攻击。跨站脚本攻击(XSS)就是典型的例子。
跨站脚本攻击在下一章中会详细讲述,这里,我们先利用刚才试验的例子来解释一下其攻击方式。在使用 iframe 外层的 JavaScript 访问内层(其他主机)数据时由于违反同源策略,访问会被拒绝。但是,这种情况下却可以使用一些特殊手段将 JavaScript 放到 iframe 的内层去执行。由于在 iframe 内层不会受到同源策略的限制,因此就能够成功访问文档信息。这种攻击就叫作跨站脚本攻击(XSS)13 。XSS 将在 4.3 节详细讲述。
图 3-29 XSS 通过将 JavaScript 放到内层从而在同源的环境下来执行
专栏:第三方 JavaScript
虽然 XSS 是因不怀好意的第三方执行 JavaScript 而产生的问题,但有些情况下我们也会需要执行第三方 JavaScript。而为了安全上的考虑,网站运营者或者网页浏览者通常执行的是他们信任的第三方 JavaScript。
- 网站运营者执行所信任的第三方 JavaScript
网站运营者有时会将第三方 JavaScript 嵌入到自己的网站中。典型的例子为,访问解析、横幅广告、博客插件等。这种情况下,运营者会有意将第三方的 JavaScript 嵌入到网页中。
嵌入的 JavaScript 如果是恶意代码,网站就有信息泄漏或遭到篡改的风险。所以,JavaScript 提供方值得信赖当属前提条件。但是,基于以下种种威胁,现实中安全问题却屡屡发生。
- 提供方有意收集个人信息
- 提供方的服务器存在安全隐患,JavaScript 代码被调包
- 提供方的 JavaScript 代码存在安全隐患而被迫运行其他脚本
网站横幅广告用的 JavaScript 和 XSS 用的 JavaScript,从技术角度来看其危险程度是相同的。两者的区别仅是网站运营者对提供方信赖与否的问题。因此,即使有意嵌入第三方 JavaScript,也需要在充分调查提供方信赖度的基础上,慎重作出判断。
- 网页浏览者信任第三方而向网页中嵌入 JavaScript
Firefox 的插件 Greasemonkey,就是网页浏览者信任第三方而向网页中嵌入 JavaScript 的例子。Greasemonkey 能让用户通过安装各种脚本从而轻易改变浏览中的网页内容。
Greasemonkey 运行时通常比 JavaScript 拥有更强的权限,所以,假如 Greasemonkey 脚本的作者心怀不轨,就能够进行盗取密码等非法操作。
- 网站运营者执行所信任的第三方 JavaScript
10 32-001.html 含有 XSS 漏洞。详情参考 4.3 节。
11 主机方面,通过 JavaScript 修改 document.domain 可以使条件放宽,但至少也被限制在了相同域名中不同主机之间的访问。
12 i-mode2.0(日本 NTT DoCoMo)的手机浏览器的同源策略中添加了目录访问的限制。
13 这里所讲解的是使用 iframe 来进行 XSS 攻击的情况,但其实不用 iframe 也同样能发动 XSS 攻击。
JavaScript 以外的跨域访问
前面讲解了 JavaScript 的跨域访问会受到同源策略的严格限制。下面,让我们来看一些能够进行跨域访问的其他浏览器功能。
- frame 元素与 iframe 元素
通过前面的试验可知,iframe 元素与 frame 元素能够进行跨域访问,但通过 JavaScript 却不能跨域访问 iframe 中的文档内容。
专栏:X-FRAME-OPTIONS
X-FRAME-OPTIONS 是微软公司提出的一种限制 frame 和 iframe 访问权限的方案,现已被 IE、Firefox、Google Chrome、Safari、Opera 等主流浏览器的最新版采用。
X-FRAME-OPTIONS 被定义在响应头信息中,值为 DENY(拒绝)或 SAMEORIGIN(仅限同源)。指定了
DENY
的响应将不能显示在 frame 等的内层中,而 SAMEORIGIN 的情况下则仅当与地址栏上显示的域名为同源时才能够被显示。在 PHP 中将 X-FRAME-OPTIONS 指定为 SAMEORIGIN 的方法如下。
header('X-FRAME-OPTIONS: SAMEORIGIN');
X-FRAME-OPTIONS 还可以用来防范点击劫持(Clickjacking)14 。通过将不使用 frame 或 iframe 的网站指定为
DENY
,使用 frame 并且使用单一主机的网站指定为 SAMEORIGIN,就能够更好地防御利用 frame 执行的各种攻击。 - img 元素
img 元素的 src 属性能够指定其他域名。这时,请求图像时会附带图像所在主机的 Cookie,所以就能够让恶意网站上的图像显示为“此图像需要认证”。
JavaScript 无法访问图像文件内部,所以跨域图像访问通常不会造成什么问题。如果不想让自己的图像被贴到某些特定网站,则可以针对图像检验 Referer 消息头。
不过这样会使关闭了 Referer 的用户无法看到图像。
- script 元素
通过指定 script 元素的 src 属性就能够从其他网站来读取 JavaScript。这里假设 A 网站读取 B 网站的 JavaScript,如图 3-30 所示。
图 3-30 跨域读取 script
JavaScript 的源代码位于 B 网站的服务器中,但是 JavaScript 被读取后,它的作用范围就变成了读取它的 HTML 所在的 A 网站。因此,JavaScript 执行
document.cookie
后得到的便是 A 网站上的 Cookie 信息。A 网站向 B 网站发送取得 JavaScript 的请求时,也会同时向 B 网站发送 Cookie。因此,根据用户在 B 网站中的登录状态,B 网站的 JavaScript 的代码有可能会发生变化,从而影响 A 网站中的内容。
这种情况也有可能会伴随着 JSONP(JSON with padding)而出现。JSONP 是从 Ajax 应用来访问不同来源的服务器中的数据时所采取的一种方式,但是根据认证状态的不同,JavaScript 的代码(JSONP 的数据)会发生变化,从而就有可能会导致意想不到的信息泄漏事故。所以 JSONP 是不能用于传送隐私信息的。
- CSS
CSS(Cascading Style Sheets)能够被跨域读取。具体来说,除了 HTML 的 link 元素之外,也能在 CSS 中使用
@import
,或者使用 JavaScript 的addImport
方法。一般来说,即使读取不良网站的 CSS 也不会造成问题。但以前在 Internet Explorer 中出现过叫作 CSSXSS 的安全隐患 15 ,它能使 HTML 或 JavaScript 被当成 CSS 读取,而如果其中部分代码能被执行的话就会有危险。
由于 CSSXSS 超出了本书的范围,因此在此不做详述。并且 CSSXSS 属于浏览器的漏洞,无关应用程序,所以只需要提醒网站用户使用最新的浏览器(如 IE8),并安装官方的安全补丁即可。
- form 元素的 action 属性
form 元素的 action 属性也能够跨域指定。而且无论 action 的目标是否跨域,form 的提交都能通过 JavaScript 来操作。
恶意利用 form 元素的特性来实施攻击的方式被称为跨站请求伪造(CSRF)。CSRF 攻击是让用户在不知情的情况下提交 form,从而肆意使用应用中的功能。关于 CSRF 会在 4.5 节详述。
14 点击劫持是综合利用 iframe 和 CSS 而执行的一种被动攻击,使用视觉上的欺骗手段诱使用户进行操作。
15 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-4089
总结
本节讲述了被动攻击,以及浏览器用来防御被动攻击的同源策略。
被动攻击是攻击 Web 应用的一种手法,经由用户的浏览器来攻击 Web 应用程序。
JavaScript 的同源策略是浏览器防御被动攻击的代表性对策。然而,若浏览器或 Web 应用中存在安全隐患,攻击者就可以绕过同源策略而执行攻击。下一章我们就将重点讲述 Web 应用方面的防御对策。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论