大家好,我是白帽攻防录的白帽K。今天分享的是TikTok Android 高危漏洞技术。
目录
一、漏洞概述
微软在 TikTok Android 应用程序中发现了一个高危漏洞,攻击者只需让用户点击一次,即可在用户无感知的情况下劫持其账户。该漏洞的利用需要将多个问题串联在一起,目前该漏洞已被修复,微软方面尚未发现任何在野利用的证据。
攻击者可以利用该漏洞,在目标用户仅点击一个特制链接的情况下,就悄无声息地劫持其账户。随后,攻击者可以访问并修改用户的 TikTok 个人资料及敏感信息,例如:
- 公开用户的私密视频
- 以用户名义发送消息
- 以用户名义上传视频
该漏洞的核心在于:允许绕过应用内的深度链接(deeplink)校验。攻击者可以强制应用将任意 URL 加载到应用的 WebView 中,从而使该 URL 能够访问 WebView 上附加的 JavaScript 桥接(JavaScript Bridge),并向攻击者授予相应功能。
二、影响范围
TikTok 的 Android 应用有两个版本:
| 版本 | 包名 | 面向地区 |
|---|---|---|
| TikTok(东亚/东南亚版) | com.ss.android.ugc.trill | 东亚、东南亚 |
| TikTok(其他地区版) | com.zhiliaoapp.musically | 除印度外的其他地区 |
两个版本在 Google Play 商店中的累计安装量超过 15 亿次。
在对 TikTok 进行漏洞评估时,微软确认这些问题同时影响两个版本的 Android 应用。在仔细评估影响后,微软安全研究人员根据其负责任披露政策,通过微软安全漏洞研究(MSVR)的协调漏洞披露(CVD)机制,于 2022 年 2 月 将问题通报给了 TikTok。TikTok 迅速作出响应,发布了修复补丁,该漏洞现已被标识为 CVE-2022-28799。
三、技术原理:JavaScript 接口与桥接
3.1 WebView 与 JavaScript 接口
该漏洞的利用依赖于应用对 JavaScript 接口的实现,这些接口由 Android 操作系统的一个组件——WebView 提供。WebView 允许应用程序加载和显示网页,并通过 addJavascriptInterface API 调用提供桥接功能,使网页中的 JavaScript 代码能够调用应用中某个特定类的 Java 方法。
安全风险:将不受信任的 Web 内容加载到 WebView 中,同时让 JavaScript 代码可以访问应用级别的对象,会使应用面临 JavaScript 接口注入风险,可能导致数据泄露、数据损坏,在某些情况下甚至导致任意代码执行。
下面是一个使用 JavaScript 接口的示例代码,JsObject 类的实例被注入到 WebView(第 8 行),并在 JavaScript 代码中通过 injectObject 变量引用,通过 loadUrl API 方法加载(第 10 行):
// 图 1:向 WebView 对象添加 JavaScript 接口
1 class JsObject {
2 @JavascriptInterface
3 public String toString() { return "injectedObject"; }
4 }
5
6 webView.getSettings().setJavaScriptEnabled(true);
7
8 webView.addJavascriptInterface(new JsObject(), "injectedObject");
9
10 webView.loadUrl("file:///android_asset/demo.html");

在 Android API 级别 18(2013 年随 Android 4.3 发布)之前,被注入类的任何方法都会暴露给这段 JavaScript 代码。从 API 级别 18 开始,只有带有
@JavascriptInterface注解(如上第 2 行所示)的类方法才能被调用。
3.2 JavaScript 桥接
TikTok for Android 大量使用 JavaScript 接口,以增强应用内使用的 WebView 能力。研究人员确定了一个使用此类 WebView 的类,它注册了一个 JavaScript 桥接,该桥接可以访问由 [redacted].bridge.* 包中各类实现的全部功能。

该桥接暴露的方法中,参数 arg1 对应一个 JSON 字符串,其中 func 和 params 属性最为关键:
func:对应从 JavaScript 代码中调用的 Java 方法名params:设置该方法所接收的参数
例如,要从 JavaScript 代码中调用签名为 String foo(String arg1, String arg2) 的 Java 方法,需使用以下语句:
// 图 3:通过 JavaScript 接口调用 Java 方法
const result = injectObject.call({
func: "foo",
params: ["value1", "value2"]
});

结果会以 JSON 字符串的形式返回给 JavaScript 代码中定义的回调函数。整体交互流程如下:
- 应用程序将网站
example.com加载到其 WebView 中 - 从远程服务器获取的 JavaScript 代码调用 Java 方法
- 该方法被执行
- 结果作为参数返回给回调函数
handler方法可在本地处理结果,或使用XMLHttpRequest将其发送到外部服务器(攻击中可借此将被盗数据发送到攻击者服务器)

四、漏洞成因:深度链接(Deeplink)校验绕过
4.1 什么是深度链接
在 Android 操作系统中,**深度链接(deeplink)**是一种特殊的超链接,链接到移动应用内的特定组件,由 scheme(协议)和(通常还有)host(主机)部分组成。当用户点击深度链接时,Android 包管理器会查询所有已安装应用,确定哪个应用能处理该链接,然后将其路由到声明为处理者的组件。
若要在应用上下文之外被其他组件使用,深度链接必须在应用的清单文件(Manifest)中声明:
<!-- 图 5:在清单文件中添加 intent filter 进行深度链接 -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="example" android:host="gizmos" />
</intent-filter>

当有多个应用能处理同一个 scheme 时,系统会弹出**歧义对话框(ambiguity dialog)**让用户选择。为了避免 http/https scheme 的歧义对话框,应用可以通过 autoVerify 属性声明 Android 应用链接(App Link),并在 https://domain.name/.well-known/ 目录下发布包含包名及证书 SHA256 指纹的 JSON 文件。TikTok for Android 对 m.tiktok.com 域使用了这一功能。

内部深度链接:除了清单文件中导出的深度链接,应用还可以用内部深度链接在组件间交换数据。若从应用外部(如浏览器)打开内部深度链接,系统会返回"无法解析 Intent"错误,因为系统无法将其路由到适当处理者。
4.2 漏洞发现
在审查应用对特定深度链接的处理时,研究人员发现了一些问题,这些问题被串联起来后,可以迫使应用将任意 URL 加载到 WebView 中。通过为该 URL 附加额外的查询参数,可以注入一个 JavaScript 桥接实例,从而获得对 [redacted].bridge.* 包所实现功能的完全访问权限。
4.3 触发应用的内部深度链接
TikTok for Android 使用了多种深度链接 scheme,其中 https://m.tiktok[.]com/redirect 链接由 [redacted] 类处理,用于通过查询参数将 URI 重定向到应用的各个组件。
研究人员确认:可以通过查询参数触发内部深度链接并调用未导出的 Activity,从而扩大应用的攻击面。

作为概念验证,研究人员构造了一个 URL,使用某个特定的未导出 scheme 将 https://www.tiktok[.]com 加载到应用的 WebView(图 8 成功加载);而 Example.com 则被应用过滤器拒绝(图 9),提示"该链接可能不安全"。


[redacted-scheme]://webview?url=<website>
过滤是在服务端进行的,加载或拒绝 URL 的决定基于某个特定 HTTP GET 请求的回复。然而,研究人员的静态分析表明,可以通过向深度链接添加两个额外参数来绕过服务端检查。
一旦绕过成功,附加到该 Activity 的 WebView 会创建 JavaScript 桥接的实例。从此时起,分配给查询参数的网站对 JavaScript 桥接拥有完全访问权限,可调用 [redacted].bridge.* 包下任何已暴露的功能。
五、已暴露的功能与攻击面
审查加载到 WebView 中的 JavaScript 代码可访问的功能后,研究人员发现了 超过 70 个已暴露的方法。当与劫持 WebView 的漏洞利用相结合时,攻击者可调用这些方法:
- 访问或修改用户的隐私信息(如私密视频、个人资料设置)
- 对任意 URL 执行经过身份验证的 HTTP 请求(方法接受 JSON 字符串参数构造 POST 请求正文,并返回服务器回复及响应头)
通过调用这些方法,攻击者可以:
- 窃取身份验证令牌——触发对受控服务器的请求,记录 Cookie 和请求头
- 检索或修改账户数据——触发对 TikTok 端点的请求,通过 JavaScript 回调获取回复
简而言之,只要控制了任何能够执行经过身份验证的 HTTP 请求的方法,恶意行为者就可能攻陷 TikTok 用户账户。
六、攻击链路:概念验证(PoC)
完整攻击流程如下:
- 攻击者向目标 TikTok 用户发送特制链接
- 用户点击链接后,攻击者的服务器
https://www.attacker[.]com/poc获得对 JavaScript 桥接的完全访问权限 - 攻击者服务器返回一个包含 JavaScript 代码的 HTML 页面,该代码将视频上传令牌发送回攻击者,并修改用户个人简介
- 视频上传的身份验证令牌通过
XMLHttpRequest发送回攻击者(含请求头与响应头)


- 最终,用户个人简介被修改为
"!! SECURITY BREACH !!!"

整个过程中,用户仅需点击一次链接,全程无感知。
七、JavaScript 接口的安全最佳实践
从编程角度来看,使用 JavaScript 接口存在重大风险:被攻陷的 JavaScript 接口可能允许攻击者使用应用的 ID 和权限执行代码。微软建议开发者社区采取以下防护措施:
核心建议
- 使用受信任域的批准列表(白名单),仅加载白名单内的域到 WebView,防止加载恶意内容
- 使用默认浏览器打开不属于应用批准列表的 URL
- 保持批准列表及时更新,并跟踪所包含域的到期日期(防止攻击者认领已过期域名劫持 WebView)
- 避免使用部分字符串比较方法将 URL 与白名单比对验证
- 避免将暂存(stage)或内部网络域加入白名单(这些域可能被伪造)
给普通用户的防护建议
- 避免点击来自不受信任来源的链接
- 始终保持设备和已安装应用为最新版本
- 切勿安装来自不受信任来源的应用
- 立即向厂商报告任何异常应用行为(如无用户交互下的设置更改)
八、总结与思考
本案例展示了 WebView 的 JavaScript 桥接机制在缺乏严格输入校验时可能带来的严重安全风险,以及深度链接校验被绕过后攻击面的急剧扩大。
几个值得关注的技术要点:
- JavaScript 接口是一把双刃剑——它在提升 WebView 能力的同时,也将 Java 层的能力暴露给了不可信的前端代码
- 服务端校验并非万无一失——通过构造额外参数即可绕过,安全校验应当纵深防御、多道把关
- 内部深度链接可被外部触发——扩大了攻击面,需谨慎处理未导出组件的可达性
该漏洞由微软安全研究人员 Dimitrios Valsamaras 发现,微软通过协调漏洞披露(CVD)机制于 2022 年 2 月通报 TikTok。TikTok 在不到一个月内发布了修复版本,漏洞被评定为高危(CVSS 8.3)。这体现了安全社区内跨行业协作在缓解安全威胁中的重要作用。

参考来源:
- Microsoft Security Blog: Vulnerability in TikTok Android app could lead to one-click account hijacking
- WebView | Android Developers
- Remediation for JavaScript Interface Injection Vulnerability – Google Help
免责声明:本文基于微软官方安全报告翻译整理,仅供技术学习与安全研究交流使用。
如果这篇文章对你有帮助,别忘了 👍 点赞、⭐ 收藏、💬 评论三连支持!你的每一次互动都是我持续输出干货的最大动力!
&spm=1001.2101.3001.5002&articleId=164034003&d=1&t=3&u=c0591f6b13b04861bef704d8c19cb41f)
32

被折叠的 条评论
为什么被折叠?



