freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

跨小程序请求伪造攻击与检测
2023-07-13 15:33:46
所属地 北京

小程序(Miniapp)是在微信和Snapchat等超级应用(Super App)中执行的程序。由于小程序本质上是迷你的,因此经常需要与其他小程序通信以完成复杂任务。然而,与使用网络域(即IP地址)在不同Web应用之间重定向的Web应用不同,小程序使用超级应用程序分配的唯一全局appID在小程序之间进行重定向。然而,接收方小程序中缺乏对发送方appID的任何检查可能导致一种新型攻击,被称为跨小程序请求伪造(CMRF,Cross-Miniapp Request Forgery)。CMRF攻击造成的后果包括特权数据访问、信息泄露、促销滥用和免费支付。

本研究揭示了此攻击的根本原因,并开发了一个名为CmrfScanner的检测工具,用于扫描存在此漏洞的小程序。CmrfScanner能够基于小程序代码的抽象语法树进行CMRF漏洞的静态检测,以确定是否缺少对appID的检查,工具源代码地址为:https://github.com/OSUSecLab/CMRFScanner 。

0x01 简介

越来越多的超级应用(微信、百度、抖音和Snapchat)都在探索新的方法来利用其庞大的用户群,并扩展其功能以获取更多利润。其中一种重要方式就是微信于2017年推出的“小程序”。小程序是轻量级且成熟的应用程序,在主机应用程序创建(或虚拟化)的JavaScript引擎内执行。凭借其易于访问和免安装的特点,以及提供打车、在线购物等无数日常生活服务,小程序在用户中迅速获得发展势头,为超级应用程序提供商和第三方开发商带来了巨大机会。截至2022年第一季度,小程序的月活跃用户数已高达12.9亿,仅微信小程序在2021年的累计交易总额达到2.72万亿元人民币。

与传统的网络应用程序或原生移动应用程序相比,小程序具有易于开发和分发的特点。具体来说,与通常需要开发人员维护后端服务器的Web应用程序不同,小程序不需要开发人员强制使用后端。相反,它提供了一组封装良好的API,可以轻松访问后台维护的超级应用程序-终端数据(例如用户名、性别和家庭住址)和系统资源(例如蓝牙、GPS和摄像头)。除了通过传统应用程序商店进行分发,小程序还可以通过聊天消息、用户动态推送甚至仅仅是二维码,利用超级应用程序的社交网络进行分发。用户只需点击一下即可使用小程序,无需安装或卸载它(即无需安装)。因此,小程序创造了三赢的局面:开发者降低了开发成本,用户可以方便地获得各种服务,平台获得了知名度、用户粘性和更多利润。

与传统的网络应用或主机应用类似,小程序通常需要协同工作才能完成复杂的任务。例如,购物小程序(Shopping Miniapp)可能需要与支付小程序(Payment Miniapp)进行交互,使用订单ID和价格等附加信息来完成购买交易。这种交叉通信尤为重要,因为单个小程序通常具有较少的功能,并受限于大小限制(例如微信小程序的大小不能超过12MB)。相比之下,原生应用程序更加灵活。此外,小程序不仅可以像传统的Web应用程序一样与后端进行通信,还需要在前端进行类似于主机应用的跨小程序通信,这类似于传统的进程间通信(IPC)。因此,超级应用程序发明了一种类似于Android Intent机制的通信方式,允许一个小程序重定向到另一个小程序。同时,当一个小程序向另一个小程序发起重定向请求时,它可以通过设置一个特殊的JSON对象,类似于主机应用程序的Intent,名为extraData,来传输特定的数据给其他应用程序。

在交叉通信过程中(包括前后端),由于传输的隐私敏感数据以及通信的小程序(特别是接收方小程序)可能具有的特权,超级应用需要添加严格安全策略和机制,以保护数据在传输和消费过程中的安全性。因此,微信等超级应用强制执行了小程序与其后端通信的强制性HTTPS协议。然而,前端安全通信的执行存在缺陷(例如,没有对发送方小程序的来源进行完整性检查)。同时,通信通常是小程序特定的,从超级应用的角度很难确保安全性。例如,当支付小程序完成支付处理时,需要通知购物小程序。然而,当购物小程序收到来自支付小程序的反馈时,购物小程序而不是超级应用有责任检查该反馈是否确实来自预期的小程序。因此,小程序有责任检查消息的真实性和完整性。

因此,接收方小程序(特别是具有特权的接收方小程序)在没有对发送方小程序的身份(即appID)进行任何缺失检查的情况下,可能允许攻击者伪造虚假请求并将其注入接收方小程序。这种攻击称为跨小程序请求伪造(CMRF),它可以导致各种安全漏洞。

0x02 研究背景

A. 小程序资源管理

通过调用超级应用提供的相应API,小程序可以访问丰富的资源。由于这些资源大部分都是隐私敏感的,因此主机应用程序以及底层操作系统必须正确保护这些资源。本文中使用主机应用程序来表示为小程序提供运行时环境的应用程序,并使用超级应用来表示包括小程序和主机应用程序在内的整个应用程序。较高级别的保护可以分为基于许可、基于隔离、基于白名单和基于审查的方法。根据资源所在位置,下表描述了它们的保护方式。

image

前端受保护资源:前端资源可以通过主机应用程序和底层操作系统的权限机制来保护,也可以仅通过操作系统的隔离机制来保护。具体来说,超级应用的前端可以通过权限机制来检查某个小程序在访问受保护的资源时是否具有相应的权限。例如,微信为小程序提供对操作系统级资源(例如位置、蓝牙)和从用户收集的信息(例如邮寄地址)的访问权限。同时,主机应用程序还可以利用操作系统提供的隔离机制来保护资源。例如,主机应用程序可以为每个小程序创建一个隔离空间,以防止其文件(例如配置文件)被其他未经授权的应用程序或小程序访问。

后端受保护资源:超级应用的后端需要保护资源不被未经授权的应用访问。为此,超级应用首先会验证开发者的真实性和相应的权限,在审核通过后才授予其访问权限。例如,API requestPayment并不适用于个人开发者,而适用于企业开发者。企业开发者使用此类API需要向超级应用提供商提交营业执照进行审核,获得批准后才能使用这些API。此外,超级应用的后端可以使用白名单来保护网络资源。

具体来说,小程序无法访问任意Web域,只能访问其超级应用信任的域名列表(例如,小程序不允许访问不使用HTTPS的网站)。有时,小程序开发者可以通过提供待访问域名以供批准,要求超级应用扩展白名单。

B. 跨小程序通信

与移动程序或网络程序类似,小程序也可以相互通信以完成复杂的任务。一个小程序可以通过重定向到另一个小程序来发送跨小程序请求,该请求使用其分配的小程序的程序ID(例如,微信的appID,百度的AppKey)。下面描述了超级应用程序的详细工作流程。

如下图所示,两个小程序需要经过3个阶段、8个步骤才能实现交叉通信:

1)请求创建和发送:发送方小程序首先创建请求并调用通信API;

2)建立通道:主机应用程序接收请求,并创建一个类似共享内存的通道来保存接收方小程序要使用的请求;

3)请求接收:接收方从通道获取请求。

image

接下来,对每个步骤进行更详细的解释(以微信为例):

(1)请求创建和发送

假设一个购物小程序需要与一个支付小程序通信来完成一笔支付交易。 用户按下购买按钮后,购物小程序首先需要获取价格,然后生成订单ID,然后调用小程序间通信API(步骤❶),例如wx.navigateToMiniProgram。如下图所示,通信的API具有三个参数:

1)接收方的小程序ID(即appID“wx2d495bf4b2abdecef”);

2)发送方尝试发送请求的路径URL(请注意, 接收方可以有多个路径URL,每个路径URL具有不同的功能);

3)请求通常采用extraData格式。

如下图所示,发送方小程序使用extraData传输价格和订单ID。 具体来说,extraData是一个JSON对象,其中包含请求的名称和请求的值(如第 8 行中的extraData:{Price:price})。

image

(2)建立通道

当从小程序调用交叉通信 API 时,它首先通知主机应用程序正在进行的通信请求(步骤❷)。 例如,当微信收到这个请求时,它会将发送方推送到一个运行时堆栈(称为AppBrandRuntimeContainer)中,该堆栈维护了一些迄今为止已启动的小程序(步骤❸)。 特别是,当运行栈中的小程序进入非活动状态,运行资源未释放时(微信不允许小程序后台运行),微信会释放位于栈底的小程序的资源 如果小程序保持不活动状态超过 5 分钟。 这是因为主机应用程序本身(例如微信)仍然是主机应用程序,

与操作系统(例如Android)相比,小程序的资源相对有限。它不能允许小程序继续启动(或运行)或消耗无限的资源。因此,为两个小程序(这是两个独立的进程)创建一个类似共享内存的空间来进行通信是一个可行的选择。 这种共享内存的创建很简单,微信只需将请求封装到一个名为 AppBrandInitConfig 的对象中,然后保存该对象以供将来引用(步骤❹)。 随后,微信根据发送方指定的appID启动接收方小程序(步骤❺)。

当从小程序调用通信API时,它首先通知主机应用程序正在进行的通信请求(步骤❷)。当微信收到这个请求时,它会将发送方推送到一个运行时堆栈中(称为AppBrandRuntimeContainer),该堆栈维护了已启动的小程序(步骤❸)。当运行栈中的小程序进入非活动状态并且运行资源未被释放时(微信不允许小程序后台运行),若小程序保持非活动状态超过5分钟,微信将释放位于堆栈底部的小程序的资源。这是因为与操作系统(例如Android)

# 漏洞挖掘 # app安全 # 请求伪造 # 微信小程序 # 小程序安全,小程序开发,小程序,软件测试
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录