WebRTC 安全之一

Posted on Sat 26 August 2023 in Journal

Abstract WebRTC 安全之一
Authors Walter Fan
 Category    learning note  
Status v1.0
Updated 2023-08-26
License CC-BY-NC-ND 4.0

WebRTC 的安全需要满足三个基本需求 * Authentication 用户访问需要认证 * Authorization 用户访问需要授权 * Audit 用户的访问应该可被追踪和审查

其中前两项也可以归结为 CIA

  1. Confidentiality 机密性:信息需要保密, 访问权限也需要控制
  2. Integrity 完整性:信息需要保持完整,在存储和传输过程不被未授权,未预期或无意地篡改或销毁,或者可以快速检测到被篡改
  3. Availablity 可用性: 信息可被合法用户访问并向其提供所需的功能和特性,例如拒绝服务攻击就是对可用性的破坏

WebRTC 的安全在 RFC8826 和 RFC8827 中有较为详细的阐述

结合我自己的理解,作一点总结。

以一个简单的 WebRTC 应用为例, 我们需要考虑浏览器在客户端的安全及隐私,也要考虑通信和传输的安全, 以及在服务器端的安全保密

                          +----------------+
                          |                |
                          |   Web Server   |
                          |                |
                          +----------------+
                              ^        ^
                             /          \
                    HTTPS   /            \   HTTPS
                      or   /              \   or
               WebSockets /                \ WebSockets
                         v                  v
                      JS API              JS API
                +-----------+            +-----------+
                |           |    Media   |           |
                |  Browser  |<---------->|  Browser  |
                |           |            |           |
                +-----------+            +-----------+
                    Alice                     Bob

在客户端遵循浏览器的安全模型

由于 WebRTC 基于浏览器来进行实时通信,浏览器作为客户端需要保证用户数据的安全,所以 WebRTC 在客户端依赖于浏览器的安全模型。 而现在流行的几大浏览器都遵循着浏览器的安全规范,例如沙箱模型(sandbox),同源策略SOP(Same Origin Policy),等等

沙箱机制将浏览器与计算机的本地资源隔离起来,并将脚本也进行相互的隔离。 一般来说,脚本只允许与来自同一域的资源交互 - 或者更具体地说,与相同“来源 Origin”的资源交互。一个 Origin 由 URI scheme, hostname, 和 port number 所组成。

同源策略 SOP 的限制保证了基本的安全,对于网络应用来说,如果双方都同意,跨越一个源的通信也是可以接受的。 跨源资源共享 Cross-Origin Resource Sharing (CORS) 就是允许浏览器使用已同意的目标服务器的脚本。

例如 Web 客户端发送一个请求到一个与自身域名不同的服务器 (host domain: bar.other) 其自身来自源 foo.example, 这个请求中包含 HTTP 头域 "Origin: http://foo.example"

    GET /resources/public-data/ HTTP/1.1
    Host: bar.other
    User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip,deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
    Origin: http://foo.example

    [Request Body]

然后 bar.other 这台服务器会检查 HTTP 请求头字段 Orgin 与自己的配置信息,发送回如下响应

    HTTP/1.1 200 OK
    Date: Mon, 01 Dec 2008 00:23:53 GMT
    Server: Apache/2.0.61
    Keep-Alive: timeout=2, max=100
    Connection: Keep-Alive
    Transfer-Encoding: chunked
    Content-Type: application/xml
    Access-Control-Allow-Origin: *

    [Response Body]

Web 服务器发送回 HTTP 响应头字段 Access-Control-Allow-Origin 通知 Web 客户端允许的域。 该响应头字段可以包含 "*" 以指示允许所有域,也可以包含指定域以指示指定的允许域。

除了上述的 HTTP 以及 WebSocket 请求,还有跨越站点的 DataChannel(DTLS + SCTP) 以及媒体数据的传输(SRTP), 这些需要应用程序来确保安全。

对本地媒体资源需要授权访问

WebRTC 客户端的麦克风,摄像头以及桌面屏幕都是涉及用户的隐私的高度机密的资源,需要获取用户的充分授权,并在捕获本地音频和视频流时显示明示的标识,例如“红点”,让用户知晓。

WebRTC 应用的安全

webrtc topology

1. 访问本地设备的授权


当应用发起一个 WebRTC 呼叫或者接收一个呼叫时,这意味着会对本地的设备,如麦克风,摄像头,计算机桌面内容等进行访问,用户需要做出决定是否允许这次呼叫,前提是用户必须明确地知道谁在请求访问这些资源,这些数据会传到哪里去。

有两个基本的概念模型

  • 1) 你正在发送媒体流给实体 A, 因为你想与实体 A 对话(例如实体 A 是你的母亲)
  • 2) 实体 A (例如一个呼叫服务) 请求访问用户的设备,并担保它将捕获自这些设备的媒体流发送给实体 B(例如实体 B 是你的母亲)

无论哪种情况,身份标识都是用户做出决定的核心依据。用户需要验证浏览器所连接的实体 A 的身份是否合法,是否符合自己的意愿。 实体 A 应该是一个可信的实体,至于实体 A 会不会将数据转发给实体 C, 这个不是用户所能控制的。

对于高安全等级的场景,我们还可以采取端到端加密的手段,参见之前写的笔记 WebRTC 之 Insertable Stream:端到端加密很简单

1.1 对于屏幕共享的威胁

除了摄像头和麦克风访问之外,有时我们还需要屏幕和/或应用程序共享功能。 不幸的是,与摄像头和麦克风访问相比,用户直观地分析此功能的安全隐患要困难得多。 (有关完整分析请参阅https://lists.w3.org/Archives/Public/public-webrtc/2013Mar/0024.html

比较明显的威胁就是那些“过度分享 oversharing”的例子, 用户本来以为他们在分享一个应用窗口,其实他在共享整个屏幕, 或者用户忘了关闭共享功能,忘记他们正在分享屏幕,从而泄露了机密或隐私。

不太明显的威胁涉及屏幕共享对 Web 安全模型的影响。 同源策略的一个关键部分是,站点 A 的 HTML 或 JS 可以引用站点 B 的内容并导致浏览器加载它,但是(除非明确允许)看不到结果。 但是,如果站点中的 Web 应用程序共享浏览器屏幕,则这就违反了该不变性,并会带来严重的安全后果。 例如,攻击者站点可能会请求屏幕共享,然后短暂地向用户的银行或网络邮件帐户打开一个新窗口,使用屏幕共享来读取结果显示的内容。 更复杂的攻击是打开站点的源代码查看窗口,并使用屏幕共享结果来查看防跨站点 (anti-cross-site)请求伪造令牌。

这些威胁表明,与访问摄像头或麦克风相比,屏幕/应用程序共享可能需要更高级别的用户同意。

1.2 呼叫场景与用户期望

有一些呼叫 (call) 的场景与用户的期望并不符合,有可能造成安全隐患。

1.2.1 专有的呼叫服务

第一个场景是专用呼叫服务。 在这种情况下,用户与呼叫站点有关系并重复对其进行呼叫。 用户可能希望授予呼叫服务对摄像头和麦克风的长期访问权限,而不是必须为每个呼叫授予权限。 这非常适合长期同意机制(例如,安装应用程序商店“应用程序”以指示调用服务的权限)。 这无形中造成了一些潜在的安全隐患,取决这个专用的呼叫服务到底有多么值得信任,它的安全保护功能是否足够健壮。

对于用户可能使用同一服务与许多不同的人交谈的任何类型的服务,都存在一个问题:用户是否可以知道他们正在与谁交谈。 如果我授予调用服务 A 代表我进行调用的权限,那么我就隐式授予它在需要时对我的计算机进行窃听的权限。

这表明了一种同意机制 (consent model),某应用或站点被授权进行呼叫,但仅限于某些目标实体(通过媒体平面media-plane 的安全保密机制进行识别)

1.2.2 从你所在的站点发起呼叫

另一个简单的场景是在您实际访问的站点发想呼叫。 这里的典型案例是许多购物网站上出现的“单击此处与客户代表交谈”窗口。 在这种情况下,用户的期望是他们正在他们实际访问的网站客服进行呼叫。 然而,他们不太可能愿意对这样的网站提供普遍的同意; 仅仅因为我想要一些有关汽车的信息并不意味着我希望汽车制造商能够随时激活我的麦克风。

因此,这表明需要第二个同意机制(consent model),仅在给定呼叫期间授予同意。

我们在设计此界面时必须非常小心,以避免用户只是点击。 另请注意,用户界面必须清楚地显示表明呼叫仍在继续的元素,以避免调用站点无限期地保留该呼叫而 Web UI 却没有提示。

1.3 基于来源的安全

现在我们已经描述了调用场景,我们可以开始推理安全需求。

Web 沙箱的基本单位是源 Origin,因此很自然地将同意范围限定在源上。 具体来说,如果用户已明确授权对该源的访问,则必须仅允许来自源 A 的脚本发起通信(从而访问摄像头和麦克风)。 当然,从技术上讲,拥有较粗范围的权限是可能的,但由于 Web 模型的范围仅限于源,因此这会造成困难的不匹配。

可以说,Origin 不够细粒度。 考虑这样的情况:Alice 访问某个站点并授权其进行一次调用。 如果仅根据来源表示同意,则在以后对该网站的任何访问(包括通过混搭或广告网络诱导的访问)时,该网站可能会窃听 Alice 的计算机,使用该计算机拨打虚假电话等。 虽然原则上爱丽丝可以授予然后撤销特权,但实际上特权会累积; 如果我们担心这次攻击,就需要采取其他措施。 对于此类问题有许多潜在的对策:

  • 1) 独立的同意 Individual Consent 每次调用都请求用户许可

  • 2)面向被叫方的同意 Callee-oriented Consent 仅允许呼叫给定用户。

  • 3)加密同意 Cryptographic Consent 只允许调用一组给定的对等密钥材料或加密建立的身份。

上述三种对策并不能满足所有情况, * 1)比较麻烦,而且盲目地点击确定并没有什么用,需要清楚明白地提示用户风险 * 2)限定只允许打给给定的目标用户,这个目标用户可能被恶意站点伪造,并不是那么好识别 * 3)限定在给定同等密钥的前提下才允许呼叫,在密钥的分发和管理方面需要防范风险

1.4 呼叫页面的安全属性

基于源的安全旨在防范 Web 攻击者。 但是,我们还必须考虑网络攻击者的情况。 考虑这样的情况:我已通过具有 HTTP 方案的源授予调用服务权限,例如 http://calling-service.example.com。 如果我曾经在不安全的网络(例如,热点或我自己的家庭无线网络不安全)上使用我的计算机,并浏览任何 HTTP 站点,那么攻击者就可以侵入我的计算机。

攻击过程如下:

我连接到 http://anything.example.org/。 请注意,该网站与呼叫服务无关。 攻击者修改我的 HTTP 连接以将 IFRAME(或重定向)注入到 http://calling-service.example.com。 攻击者伪造http://calling-service.example.com/的响应注入JS来向自己发起调用。 请注意,此攻击并不依赖于媒体不安全。 由于呼叫是发送给攻击者的,因此对他们来说也是加密的。 而且,并不需要立即执行; 攻击者可以半永久地“感染”源(例如,使用网络工作人员或隐藏在主窗口下的弹出窗口),从而能够在我离开受感染网络很长时间后骚扰我。 这种风险是由于允许从通过 HTTP 获取的页面进行调用而产生的。

即使只能从 HTTPS [RFC2818] 站点进行调用,如果这些站点包含来自不受信任站点的活动内容(例如 JavaScript),则该 JavaScript 会在页面的安全上下文中执行[更细粒度]。 即使父页面是安全的,这也可能导致调用受到损害。 注意:此问题不仅限于包含不受信任内容的页面。 如果来自给定来源的任何页面曾经从攻击者处加载 JavaScript,那么该攻击者就有可能半永久地感染浏览器的该来源概念。

2. 通信一致性的验证

在SDP 协商时,我们会有如下的 SDP 属性

m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:+q16
a=ice-pwd:dJytV8Z6j1MMoL1KG3rbnm8y
a=ice-options:trickle
a=fingerprint:sha-256 81:8F:AA:AE:EF:8D:B2:5C:C1:C3:00:22:47:2F:8D:C3:5B:C9:35:F2:9D:13:24:20:2A:ED:16:90:75:A1:98:BD
a=setup:actpass

其中的 ice-ufrag, ice-pwd 和 fingerprint 就是双方协商一致的通行证, 在对端发送 STUN 消息 和 DTLS 握手时对于这几项都需要验证

3. 通信的安全

实际应用中,WebRTC 应用会通过 HTTPS(https://host), SIPs 或者Secure WebSocket(wss://host) 与其他服务器进行通讯,也会通过 DataChannel(SCTP over DTLS) 和 SRTP 同媒体服务器或者 P2P 对端进行媒体传输.

webrtc protocol stack

  • SRTP [RFC3711]
  • DTLS [RFC6347]
  • DTLS-SRTP [RFC5763]

这一块需要用单独的篇幅详细谈谈

参考资料


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。