网络安全咨询公司Nightwatch发现,谷歌的Chrome浏览器,WebView和Android的Chrome标签显示了有关运行它的设备的硬件型号,固件版本和安全补丁级别的信息。这也会影响使用Chrome呈现网络内容的所有Android应用程序。此信息可用于跟踪用户和指纹设备。它还可用于确定特定设备易受攻击的漏洞,以便针对攻击。
虽然供应商(Google)在2015年拒绝了最初的错误报告,但他们已于2018年10月针对Chrome v70发布了部分修复程序。该修复程序隐藏固件信息,同时保留硬件模型标识符。所有先前版本都会受到影响。建议用户升级到70或更高版本。由于此修复程序不适用于WebView用法,因此应用程序开发人员应手动覆盖其应用程序中的用户代理配置。
供应商和MITER都拒绝发布CVE号码来跟踪此问题,因为他们认为这不涉及任何安全问题。
背景——Chrome and Headers
适用于Android的Chrome浏览器由Google提供,作为适用于移动设备的Android操作系统的默认浏览器。它基于Chromium开源项目。它还为在Android平台上运行的其他应用程序提供WebView和Custom Tabs API,用于在不打开单独的浏览器窗口的情况下,在应用程序内呈现Web内容。
与所有浏览器一样,Chrome会向与其通信的Web服务器发送各种标头作为每个请求的一部分。这些标头在HTTP协议中定义,可以在RFC7230,7231,7232,7233,7234和7235找到最新标准,其中包括User-Agent标头。
HTTP中的“User-Agent”标头由RFC 7231第5.5.3节定义如下:
user-agent”标题字段包含关于发起请求的用户代理的信息,服务器通常使用这些信息来帮助识别报告的互操作性问题的范围,处理或调整响应以避免特定的用户代理限制,以及分析浏览器或操作系统的使用。
背景——Android模型和ID构建
Android设备有内置模型和ID构建,以识别手机模型和Android构建。它们是在android.os.Build中定义的。它们在android.os.Build.MODEL和android.os.Build.ID属性中定义。这些在Android兼容性定义文档(第3.2.2节)中进一步定义如下:
MODEL-设备实施者选择的值,包含终端用户已知的设备名称。这应该与设备销售和销售给最终用户的名称相同。没有具体的形式要求。
ID-设备实现者以人类可读的格式选择引用特定版本的标识符。此字段可以与android.os.Build.VERSION.INCREMENTAL相同,但应该是一个足以让最终用户区分软件构建的值。该字段的值必须可编码为7位ASCII,并匹配正则表达式“^[a-zA-Z0-9._-]+$”。
漏洞详细信息
根据Chrome文档,Chrome for Android用户代理字符串包含Android版本号和构建代码信息。当应用程序使用Android的WebView和Chrome自定义选项卡API在自己的应用程序中提供Web内容时,也会发送这些信息。虽然Android确实提供了覆盖这些功能的能力(通过WebView中的WebSettings.setUserAgent()),但大多数应用程序选择不这样做以通过依赖默认标头来确保兼容性。
加剧问题的是,用户代理标头总是通过后台运行的进程发送,同时伴随发送HTTP和HTTPS请求。此外,与桌面浏览器Chrome不同的是,在Android,除了当前会话的浏览器本身的“请求桌面站点”选项之外,没有任何扩展或覆盖可以更改标题。
例如,针对Android版v5.1.1的Nexus 6上Chrome Beta的用户代理标头:
Mozilla/5.0(Linux;Android 5.1.1;Nexus 6 Build/LYZ28K)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/46.0.2490.34 Mobile Safari/537.36
当用户选择“请求桌面站点”选项时,发送的用户代理标头是通用Linux标头。以下是适用于Android v5.1.1的Nexus 6上Chrome Beta的示例:
Mozilla/5.0(X11;Linux x86_64)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/46.0.2490.34 Safari/537.36
不同之处在于,在移动模式下,以下字符串是额外的:
Android 5.1.1;Nexus 6 Build/LYZ28K
它识别操作系统及其版本的事实并不是唯一的。这与许多其他常见浏览器在桌面和移动设备上情况相同。构建标记是问题所在。如上所述,构建标记标识设备名称及其固件构建。对于许多设备来说,这不仅可以用于识别设备本身,还可以用于识别运行它的运营商以及所在国家/地区。它还可用于确定设备上的哪个安全补丁级别以及设备易受攻击的漏洞。
从以上例子不难看出,其中构建LYZ28K可以很容易地识别为在T-Mobile上运行的Nexus 6。使用构建信息根据已知哪些运营商在哪个构建号上来确定运营商也是微不足道的。可以从诸如此类的制造商和电话运营商网站轻松获得构建号码。
要想检查设备是否受到影响,用户可以访问显示浏览器发送的用户代理标头的任何网站,或者您可以在Google搜索中键入“查看用户代理”。或者,可以在像JsFiddle这样的网站上使用以下JavaScript:document.write(navigator.userAgent)
供应商响应和缓解建议
Bug#494452已于2015年针对Chromium提交此错误,并被供应商拒绝为“WAI”-“按预期工作”。但是,在2018年,供应商提交了一个新的错误#860229和功能请求,这部分修复于2018年10月在Chrome v70 for Android中通过从标头中删除固件构建信息,但设备型号仍然存在。
该修复程序仅适用于Chrome应用程序本身,而不适用于应用程序开发人员使用的WebView实现,如以下说明所示:
不按照Android兼容性定义文档的要求,将更改应用于Android Web View。
建议用户更新到Chrome v70或更高版本以解决此问题。应用程序作者应使用WebSettings.setUserAgent()方法来设置覆盖用户代理。虽然许多人不愿意这样做以便失去兼容性,但专家建议使用以下方法,即使用默认用户代理并删除其中的构建和模型信息。