现代浏览器中Cookie同源策略测试框架的设计与实现*

2019-12-11 02:23梁浩喆陈秀真
通信技术 2019年12期
关键词:测试用例同源浏览器

梁浩喆,马 进,2,陈秀真,2,杨 潇

(1.上海交通大学 网络空间安全学院,上海 200240;2.上海市信息安全综合管理技术研究重点实验室,上海 200240)

0 引 言

Cookie在Web应用程序(Web Application)中通常用于标识用户的身份或者记住用户的使用偏好,以便改善用户体验。Cookie的使用方法十分简单,为Web应用的编写者带来了许多便利。但是,Cookie也因其简洁的访问方式而给Web应用程序带来了一些安全漏洞,如宽泛授权(Ambient Authority)、弱机密性(Weak Confidentiality)和弱完整性(Weak Integrity)[1-2]。尽管开发者和标准制定者们想出了许多对策以减轻这些问题的影响,但由于Web文档(Document)以及同源策略(Same-Origin Policy)的复杂性,标准所覆盖不到之处总是不可避免。各类Web对象的源(Origin)的不一致性与各种能写入或者发送Cookie的请求触发方法纠缠在一起,构成了复杂的Cookie访问规则[3-4]。澄清这些规则有助于开发人员选择正确的方法来构建他们的Web应用程序,并帮助浏览器设计与开发人员找到浏览器设计与实现中的问题。

Cookie在实际应用程序中是保存在浏览器中的键值对,键为Cookie的名字,值为服务器所需存储的信息,如用户名、用户的偏好或用户的标识。一般来说,如果浏览器向服务器发送请求,Cookie将与该请求一同发送出去,服务器根据Cookie中保存的信息确定用户是否登录,且应该返回什么样的结果等。因此,一旦Cookie因为浏览器漏洞或者用户的操作失误被泄露或被替换,用户的信息也会随之泄露,使用户易遭受身份冒充攻击(Impersonation Attack)[5]。此外,恶意或受到攻击者控制的网站可能会设置Cookie来跟踪用户的行为或使正常的服务功能失常。较为典型的利用Cookie的Web攻击是跨站请求伪造(Cross-Site Request Forgery),恶意站点诱使用户触发向用户已登录的正常网站的请求,包含登录信息的Cookie将一同发送出去。通过这种方式,恶意站点可以像真正的登录用户一样要求正常网站执行一些需要特定用户权限的操作,这将对用户的账户造成损害并泄露个人信息。缓解跨站请求伪造的常用方法是在用户首次请求网站的Web文档(Web Document)时,服务端在返回的文档中嵌入一个属于该网站的令牌(Token),在其后的请求中要求浏览器附上该令牌,恶意网站没有这个令牌,故不能冒充正常的用户请求。虽然Token的方法能有效缓解跨站请求伪造的问题,但这种方法并不是用于保护Cookie,并不能阻止Cookie的发送。

为防止Cookie跨源使用,在浏览器实现时通常让Cookie的发送遵守同源策略[6]。每个Cookie都有各自的Web源(Origin)[7],对Cookie的操作是否合法是由根据同源策略所衍生出的规则确定的。同源策略是一组复杂的规则集合,尽管其覆盖广泛,但是这些规则没有明确的“学术或非学术定义”[8]。除了Cookie之外,其他诸如文档对象模型对象(DOM Objects)之类的浏览器资源都有它们自己对应的源。DOM对象的源和Cookie的源可能有所不同,但它们却可以交互。DOM文档中的对象可以发出携带Cookie的请求,或者接收写入Cookie的响应[8]。这就意味着Cookie与其他Web对象之间的交互没有明确标准与规则,同时一些复杂的嵌套与交互所产生的结果可能也与设计者的初衷不符。这些模糊的规则可能会给攻击者一些绕过保护的机会,威胁Web应用程序信息的完整性和机密性[9]。

同源策略涉及众多Web资源,不同的Web资源中又有多种方式可以触发携带Cookie的请求或者接收写入Cookie的响应。在一项研究中难以逐一描述全部的规则,所以针对这个问题的研究一般都只描述同源策略的一个子集。例如,文献[5,8,10]研究了来自不同源的DOM对象如何访问其他DOM对象里的内容;文献[4,11]研究了现代浏览器的Cookie保护措施的有效性;文献[12-13]描述了Local storage和Session storage的同源策略以及Web SQL和相关API中的同源策略。本文的研究内容是由HTML元素所写入或者发送的Cookie的同源策略,即HTML元素对Cookie的读写规则。具体来说,本文设计并实现了一个测试框架用于分析在现代浏览器中的以下内容:

(1)哪些HTML元素能够发送携带Cookie的请求,这些请求在跨源时和同源时是否能携带一样的Cookie。

(2)哪些HTML元素能够在接收的响应中写入Cookie,这些响应在由跨源的服务器发出时和由同源的服务器发出时是否能写入一样的Cookie。

(3)当有跨源的嵌套或者同源的嵌套时,上述规则会变化为怎样的规则。

(4)当HTML元素加上相应的安全属性时,或者当Cookie设置为不同属性时,上述规则会变化为怎样的规则。

1 研究背景

1.1 Cookie属性

Cookie是服务器发送给客户端的一个“名称-值”对,当客户端向该服务器发送请求时,可以将对应的Cookie附带在请求中,用来表示一些客户端的状态。一般情况下,除了名称和值之外,Cookie中还包含了一些关于Cookie本身的元数据。这些元数据和“名称-值”对由响应中的Set-Cookies首部写入,格式为“Set-Cookies:name=value optionalattributes”,其后的可选属性optional-attributes即是关于Cookie的元数据。这些元数据告诉客户端何时应该发送Cookie,如果客户端程序实现良好。遵守这些规定,Cookie将得到一定的保护。

Cookie中的元数据即Cookie的属性,共有7种。其 中,Expires Attribute和Max-Age Attribute表 示Cookie的最大生命周期,即Cookie在什么时间内有效;HttpOnly Attribute将Cookie标记为“HttpOnly”[14],即Cookie不能被诸如客户端站点脚本、flash脚本之类的非http API访问,此属性能够缓解一些跨站脚本攻击(Cross-Site Scripting Attack);“Secure”属性告诉用户代理仅通过安全通道发送Cookie,如通过HTTPS[15]发送,但是安全通道也可以是其他通道,其具体的范畴由浏览器自行定义;“sameSite”属性由HTML5引入[16],拥有这个属性的Cookie仅能通过同一站点请求发送。此功能是为了保护Cookie,缓解CSRF攻击,该属性有两个值——Strict和 Lax。

“Domain”属性和“Path”属性指明Cookie应该被发送到的位置,只有“Domain”字段与请求的地址域相同或者是其子域时,Cookie才可以被发送。类似地,如果Cookie路径与请求路径的前缀相同或是其前缀,则允许将发送Cookie。域和路径提供了一些区分不同Cookie的方法,但过于依赖这些功能可能会产生Web应用中的安全漏洞。例如,来自子域sub.domain.com的响应可以将“Domain”属性设置为domain.com,这些类型的Cookie可以发送到domain.com域或该域的其他子域,如another.domain.com。

1.2 同源策略

1.2.1 Web源

RFC 6454[7]给出了Web源的定义,文档中称Web Origin“通常被用户代理(User-Agent)用于限定权限(Authority and Privilege)的范围”,但是该文档只是详细定义了一种Web源,即“URI(统一资源标识符)Web Origin”及其相关的规则,而其他的Web资源(Resource)未被定义,并不遵守这一套规则。同源策略的根本原则是隔离不同的Web资源,使每个Web资源属于一个源,在对其他Web源中的Web资源的访问时将受到限制,并遵循名为“跨源资源共享(Cross Origin Resource Shared)”的规则[17-18]。URI Web Origin是一个由协议、域、端口组成的三元组[19],当某一URI与另一URI的这三种属性都相同时才属于同一个源,例如,以下URI具有不同的来源:

HTTPS://cookie.test:80

HTTP://cookie.test:80

HTTPS://cookie.test:8080

HTTPS://localstorage.test:80

下列URI有相同的源:

HTTPS://cookie.test/tag/img

HTTPS://cookie.test/tag/iframe

需要注意的是,对于DOM Web资源来说,URL的域部分一般是主机(Host)名。Host一般指的是“由封装在方括号内的点分十进制形式的IPv4地址或注册名称”构成的标识[20]。

1.2.2 同源策略的不一致性

一个Web文档中的Web资源不一定与该文档的源相同。URI Web Origin仅适用于某些Web资源,如DOM对象、本地脚本等,而其他的Web资源有其自己的关于“源”的定义。例如,Cookie的源与DOM对象的源略有不同,因为Cookie源不包括端口,这意味着Cookie可能被发送到在同一服务器上正在运行的不同进程,因此Cookie的同源策略与HTML元素的同源策略在实现中是有区别的。嵌入式HTML元素(embedded HTML Element)可以将属于外部源的Web资源引入文档,同时可以写入和发送Cookie。这种通过HTML元素请求(或响应)写入(或发送)Cookie的跨源操作是一个未明确定义的操作,需要进行测试以了解用户代理(通常是浏览器)是如何处理这种情况的。

2 Cookie访问模型设计

2.1 访问规则描述

为了清楚地描述通过HTML元素对Cookie进行写入或读取的规则,本文定义了一种访问模型。在该模型中,进行访问的主体是HTML元素,被访问的对象是浏览器中的Cookie。影响访问控制的因素包括HTML元素本身及其属性以及上述Cookie的属性,共9个因素:(1)HTML元素;(2)HTML元素属性;(3)Cookie;(4)Cookie属性;(5)请求源;(6)目的源;(7)请求触发器属性;(8)HTTP模 式(schema);(9) 请 求 方法。模型中,HTML元素可以对Cookie执行两个操作,即写Cookie(Write Cookie)和读Cookie(Read Cookie)。每一条读写规则以及每个测试用例都是上述9个因素和两个操作的组合,。

2.2 访问属性诠释

2.2.1 读cookie操作

一个HTML元素可以读取一个Cookie意味着由该HTML元素触发的浏览器请求可以携带该Cookie。例如,如果标签 <img src=“store-cookie_endpoint”/>可以向服务器发送带有“name=value”cookie的请求,意味着标签img可以读取Cookie“name=value”。

2.2.2 写Cookie操作

一个HTML元素可以写一个Cookie,意味着浏览器会根据与由该HTML元素触发的请求所对应的响应中的Set-Cookie响应头来设置Cookie。例如,如果标签 <img src=“set-cookie_endpoint”/>向服务器发送请求,服务器返回带有Set-Cookie:name=value响应头的响应,浏览器在接收到响应后设置了Cookie“name=value”,表明标签img可以设置Cookie“name=value”。

2.2.3 HTML元素属性

某些HTML元素属性会影响Cookie的发送,如<iframe>的sandbox属性,另一些属性如<link>中的ref会影响请求是否被触发。

2.2.4 Cookie属性

如1.1节中所述。

2.2.5 请求源和目的源

发送源和目标源分别是请求发出的域和请求发送到的域。

2.2.6 请求触发器属性

HTTP标准中的一些URI属性[21],是可触发HTTP请求的属性,如src、href以及data。

2.2.7 HTTP模式和请求方法

HTTP模式可以是“http”或“https”,请求方法即HTTP协议的请求方法,如GET、OPTION、HEAD等,而HTML元素请求中的请求方法通常是GET。当Cookie具有“Secure”属性或“HttpOnly”属性时,请求方法会影响Cookie是否随请求一起发送。

3 框架实现

本文设计的测试工具为一个Web应用程序,其工作方式与普通的Web应用程序相同,以便检测浏览器在实际使用时的表现。前端测试应用有两种模式:一种是预定义模式(见图1),前端应用程序可以根据用户所选定的元素和属性向后端应用发送请求,加载一些预先设计好的HTML元素测试用例;另一种是自定义模式(见图2),允许由用户在前端页面中添加一些新设计的测试用例,包括HTTP元素的嵌套、元素属性的自定义和Cookie属性的定义等。后端应用程序负责解析请求,检查Cookie是否存在,存储请求信息,包括Cookie(如果存在的话)。前端应用程序将在后续步骤中获取测试结果,并将其显示给用户。

图1 预定义模式测试程序

图2 自定义测试模式测试程序

3.1 框架结构

本文设计的测试框架包含4个主要部分(如图3所示):1个前端Web应用程序、2个后端应用程序和1个用于存储请求信息的共享存储,且该存储由2个后端程序共享。前端应用程序可以从后端应用程序加载默认测试用例,或从用户输入中生成测试用例;被测试的HTML元素将挂载在前端程序提供的页面上。在该页面上,HTML元素将尝试触发对后端“set-cookie”节点(endpoint)或者“store-cookie”节点的请求。请求的节点不同,所进行的测试也不同,根据所请求的节点,进行的测试将分为写入测试和读取测试。此外,前端程序还负责从后端获取测试结果的信息,并将它们有组织地展示在页面中。

图3 测试框架的结构

两个后端应用程序的域名是不同的,一为“firstparty.test”,二为“third-party.test”,分别作为测试中的第一方源和第三方源。第一方为发出跨源请求的源,第三方为接收跨源请求的源。在测试中,第一方同时也发出同源请求作为对照。每个后端应用都有“set-cookie”和“store-cookie”两个节点。“setcookie”节点用于写入测试,根据测试需求尝试对浏览器写入Cookie。具体来说,该节点返回带有“Set-Cookie”响应头的响应,响应头的值将根据前端应用的请求参数设置,可以包括任何Set-cookie属性,如“HttpOnly”“sameSite”等。“store-cookie”节点用于读取测试,接收HTML元素触发的请求,判断其中是否包含Cookie;如果包含Cookie,后端程序便将与Cookie相关的信息储存起来,即在共享存储中存储被发送的Cookie和它们所具有的属性。此外,第一方应用负责将测试结果发送到前端应用程序。

3.2 框架工作流程

测试工具的完整工作流程如图3所示。要对一个测试用例进行一次测试,前端首先从后端加载测试用例信息或自定义输入用例信息,生成带有指定安全属性的HTML标签。标签包括可以触发请求的属性,该属性指向需要进行测试的后端节点,然后将该标签挂载在页面上。浏览器会解析HTML标记,并根据其实现决定下一步要做什么。每一次测试都包括对该测试用例的读测试和写测试,每个写测试和读测试都会分别向第一方应用和第三方应用发起请求。因此,对一个测试用例进行测试,会发送4个测试请求。在4个请求都完成后,后端应用会将测试结果返回给前端用户。为清晰起见,这里给出一次测试的完整过程:

算法1:对一个测试用例进行一次完整的测试

输入 测试用例信息 test_case_info

输出 测试结果 test_result

1.generateTags(test_case_info);

2.//write test

3.mount(write_tag_point_to_same_site);

4.mount(write_tag_point_to_cross_site);

5.sendToBackend(Cookie_be_written);

6.//read test

7.setCookie(Cookie_should_be_read);

8.mount(read_tag_point_to_same_site);

9.mount(read_tag_point_to_cross_site);

10.test_result=fetch(same_site_test_result);

11.test_result+=fetch(cross_site_test_result);

3.3 测试举例

对于测试用例(图2),有:<iframe sanbox=“allow-script”

src=“http://thirdpaty.test/store-cookie”>

假设浏览器中存在带有“HttpOnly”属性的第三方Cookie“external=third-party”,同时第一方文档中存在一个嵌入式元素<iframe>,它指向第三方应用的读取测试节点“store-cookie”,那么对应的测试结果将表示为9个因素组合而成的一条规则,如表1所示。

表1 测试结果举例

如果后端能够接收到Cookie,那么结果可以解释为:带有sandbox=allow-script属性且指向第三方节点的HTML元素iframe可以读取带有HttpOnly属性的第三方Cookie;反之,如果服务器无法接收任何Cookie,那么说明该元素不能读该Cookie。写入测试结果可以用类似的方式解读,只要将规则中的读取操作替换为写入操作即可。

图4为测试结果示例。

图4 测试结果示例

4 结 语

为厘清通过HTTP元素进行Cookie跨源读写的规则,以帮助应用开发者构建更为安全的Web应用,以及帮助标准制定者制定更合理的Cookie读写标准,本文设计了一种针对现代浏览器的测试框架。该框架便于测试人员控制与跨源访问相关的9个变量,能够确定在复杂环境下主流浏览器的实际行为。此外,该框架的实现具有可扩展性,能够依据测试者的意愿即时构造测试用例和测试页面进行测试,增加了测试的灵活性,为以后进一步的研究奠定了基础。

猜你喜欢
测试用例同源浏览器
基于“乙癸同源”理论辨治股骨头缺血性坏死
测试用例自动生成技术综述
以同源词看《诗经》的训释三则
回归测试中测试用例优化技术研究与探索
基于SmartUnit的安全通信系统单元测试用例自动生成
“铤”有“直”义的词源学解释——兼说/直/义的同源词族
微软发布新Edge浏览器预览版下载换装Chrome内核
反浏览器指纹追踪
同源宾语的三大类型与七项注意
软件回归测试用例选取方法研究