Titanium Browser 安全加固实战:Scheme 守卫、UAF 漏洞修复与离线扩展安装防护机制解析
【免费下载链接】android-titanium-browserSecure open-source Android browser with support for extensions项目地址: https://gitcode.com/gh_mirrors/an/android-titanium-browser
Titanium Browser 是一款安全、完全开源的 Android 浏览器,基于 Chromium 与 Vanadium 构建,并原生支持扩展。它通过在构建阶段注入大量定制补丁(Scheme 守卫、UAF 漏洞修复、离线扩展安装防护等),在开源浏览器中提供了少见的"深度安全加固"方案。本文带你从三个实战角度解析这套安全机制的工作原理。
🧱 加固总览:补丁是如何注入的
Titanium Browser 的加固并非黑盒。整个项目通过一条清晰的流水线工作:
Chromium 源码 → Vanadium 通用补丁 → 额外定制补丁 → GN 构建配置 (args.gn) → 签名发布- 核心定制补丁全部由 patch.sh 脚本驱动,使用
sed精准修改 Chromium 源码; - 构建参数集中在 args.gn,其中
use_rtti = false(禁用 RTTI)、dcheck_always_on = false等配置从编译层面收敛攻击面; - V8 层面开启
v8_drumbrake_bounds_checks = true,为 JavaScript 引擎加上边界检查保险丝; - 签名发布工具位于 common.sh,保证每次 APK/AAB 都用同一密钥签名,可被验证。
💡 所有加固补丁都集中且可读,任何人都可以逐行审计——这正是开源安全的核心价值。
🛡️ Scheme 守卫:拦截恶意 Intent 的第一道门
为什么需要 Scheme 守卫?
Android 上任何应用都可以发送ACTION_VIEWIntent 唤起浏览器。如果浏览器不加筛选地处理 Intent 携带的 URL,恶意应用就能构造javascript:、自定义 Scheme 或内部调试页面链接,诱导甚至欺骗浏览器执行非预期行为。这就是典型的 Intent 滥用攻击面。
实现方式:只放行网络 URL
方案非常简洁——在 patch.sh#L23-L25 中,补丁修改了LaunchIntentDispatcherHooks.java的三处入口:
- 常规启动:Intent 的 URL 通过
android.webkit.URLUtil.isNetworkUrl()校验,非http(s)链接直接拒绝; - URL 为空判断:
urlFromIntent == null的判断同样升级为网络 URL 校验; - Custom Tab 入口:
maybeModifyCustomTabIntents开头增加同一守卫,防止从其他应用以自定义标签页方式绕过。
一句话概括:只有真正的网络地址才能进入浏览器,其余一律原样返回、不做处理。这是成本极低、收益极高的安全模式。
🩹 UAF 漏洞修复:让"悬垂指针"无处可查
Use-After-Free(UAF,释放后使用)是浏览器内核中最危险的一类内存漏洞之一——程序访问了已被释放的对象,轻则崩溃,重则可被利用执行任意代码。Titanium Browser 针对隐身(Incognito/OTR)场景修复了两处 UAF 问题:
修复一:tabs API 的空 tab_list 越界(crbug.com/431004500)
在 patch.sh#L153-L154 中,补丁向tabs_api.cc的标签遍历循环注入了一个空指针守卫:
if (!tab_list) { continue; }扩展调用 tabs API 枚举标签页时,若 tab_list 已被释放,原代码会直接解引用触发 UAF;现在会安全跳过这一轮。
修复二:禁止销毁仍有活跃内容的隐身配置(crbug.com/40274462)
这是更精妙的一处修复(patch.sh#L156-L162),分三步协同:
- 为
WebContents新增辅助函数HasLiveWebContentsForBrowserContext(),遍历所有 WebContents 检查指定配置(BrowserContext)下是否还有"活着的"内容; - 在
ProfileDestroyer::DestroyOTRProfileWhenAppropriateWithTimeout()的销毁流程中插入前置检查——只要隐身配置下还有存活的 WebContents,就立即中止销毁; - 由此避免了"配置先被释放、页面稍后才访问"的经典 UAF 竞态窗口。
本质上,这是一种"引用存在性"防护:宁可推迟销毁,也不允许在仍有使用者时回收对象。
🔌 离线扩展安装防护:白名单 + 内置扩展双重机制
Titanium Browser 支持 Manifest V2 扩展(patch.sh#L70-L73 放开了 MV2 限制),同时为"商店外安装"设计了分层防护。
第一层:可信域名白名单
patch.sh#L76 修改了download_crx_util.cc中的OffStoreInstallAllowedByPrefs(),只有以下情况才放行非商店扩展安装:
- 请求发起方 Scheme 为
chrome-extension(扩展自身的可信请求); - URL 或来源页属于白名单域名:
addons.opera.com、operacdn.com、microsoftedge.microsoft.com、edge.microsoft.com、delivery.mp.microsoft.com。
这意味着随机网站"顺手"推送的 CRX 下载会被直接拦截。
第二层:内置扩展的离线安装
对于随 APK 打包的扩展,项目用"资源 + 启动时暂存"的方式实现完全离线可用:
- extensions/bundle.py 是离线打包脚本:下载 CRX 后解析 CRX3 头部的 varint 字段,提取出扩展 ID 与版本号,登记到
bundled.json索引,并自动更新 extensions/BUILD.gn 的renaming_sources/renaming_destinations列表,将 CRX 声明为 APK 资源; - 运行时,extensions/stage_bundled_extensions.inc 中的
StageBundledExtensions()从 APK assets 读取bundled.json,逐项校验路径合法性(拒绝绝对路径与..父目录引用,防路径穿越),再内存映射读取 CRX 写入用户数据目录,最后把索引合并进外部扩展偏好; - patch.sh#L15-L17 则把该暂存流程挂钩到
external_pref_loader.cc,并在extension_safety_check_utils.cc中对kExternalPref来源的扩展做专门处理。
📋 小结:这套加固方案值得借鉴的地方
| 机制 | 防护目标 | 关键位置 |
|---|---|---|
| Scheme 守卫 | Intent 滥用 / 非网络 URL 注入 | patch.sh#L23-L25 |
| UAF 修复(tabs) | 扩展 API 空指针解引用 | patch.sh#L153-L154 |
| UAF 修复(OTR 销毁) | 隐身配置销毁竞态 | patch.sh#L156-L162 |
| 商店外安装白名单 | 任意网站诱导安装 CRX | patch.sh#L76 |
| 内置扩展离线暂存 | 路径穿越 / 离线可信安装 | extensions/stage_bundled_extensions.inc |
| 构建期收敛 | RTTI、调试断言、V8 边界检查 | args.gn |
如果你想完整体验或审计这套安全机制,可以克隆仓库自行构建:
git clone https://gitcode.com/gh_mirrors/an/android-titanium-browser安全浏览器的核心竞争力,不在于"看起来安全",而在于每一条防护都可被逐行审查、复现与验证——Titanium Browser 用补丁驱动的透明工程方式,给出了一个很好的范本。
【免费下载链接】android-titanium-browserSecure open-source Android browser with support for extensions项目地址: https://gitcode.com/gh_mirrors/an/android-titanium-browser
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考