隐藏字段自动填充可能被用于窃取用户信息,需限制范围
别名: 隐藏字段填充 · autofill harvesting · hidden input autocomplete
概念解释
浏览器有时会把保存的姓名、地址、支付资料写进用户看不见的输入里。页面随后把这些值随表单提交。限制范围指:不在隐藏、零尺寸、屏幕外或 opacity:0 的控件上放置会被自动填充认出来的姓名、地址、支付语义;非可见字段要么拿掉填充语义,要么根本不放进将要提交的表。这是防御性的范围控制,不是讲解如何构造这类页面。字段叫错名字导致可见框填错、两套来源打架,是另两件事。
机制
自动填充的启发式看的是字段语义,不是人是不是看得见。不可见控件若仍带有地址或支付令牌,可能被写上用户从未同意在这张表上交出的值。人的核对发生在可见框上,隐藏值不进核对,于是一份额外的档案离开了浏览器。第二层是可见性本身会变:折叠区、条件显隐、display:none 稍后被脚本打开,字段在填充那一拍是隐藏的,在提交那一拍是显示的,或反过来。范围规则必须按「这一拍是否对用户可见且可编辑」来决定能不能带填充语义,而不是按 DOM 里有没有这个节点。产品自己的隐藏字段(CSRF 令牌、商品 id)不应带姓名地址令牌;带了,就变成额外出口。
怎么研究
用无障碍树和计算样式列出所有输入,标出不可见但仍带填充语义的节点,看浏览器档案在聚焦可见字段时这些节点有没有被写入。
自变量:不可见方式(hidden / 零尺寸 / 屏幕外 / 折叠)、是否带标准 autocomplete 令牌、提交时是否包含这些节点。
因变量:不可见节点是否出现档案中的地址或支付片段、用户是否知情、提交载荷里是否多出可见表没有的个人数据。
不要在真实用户档案上做写入测试以外的攻击演练;用专用测试档案。审查以载荷和可见性清单为准,不以「我们没有恶意」为准。
边界
密码管理器为了无障碍可能对视觉隐藏、但对辅助技术可见的字段填充,这与「对所有人都不可见却仍提交」不是一类。合法的 honeypot 用来挡机器人,应使用不能被填充语义识别的名字,并在服务端丢弃,且不得用来存真实用户资料。原生应用的自动填充 API 有自己的可见性规则,Web 的 hidden 套不过去。调试时临时隐藏字段很容易被带进生产,发布检查要比代码评审更硬。
怎么落地
- 列出将要提交的每一个输入:对用户不可见或不可编辑的,去掉姓名、地址、支付类
autocomplete令牌,并不使用能被启发式认成这些类型的name。 - 条件显隐的字段只在真正展开且可编辑之后才带填充语义;折叠时按不可见处理。
- 提交前再扫一遍载荷:出现可见表没有展示过的个人数据即失败。
- 验证:用测试档案保存地址与支付资料,打开表单只填可见项;开发者工具里隐藏输入的值应仍为空。把一个带
cc-number的输入做成零高度,作为发布检查必须拦住的对照。折叠地址组在未展开时提交,载荷里不得出现档案地址。