如何在不需要用户互动的情况下自动填写密码字段?

时间:2017-09-17 21:02:43

标签: google-chrome passwords tampermonkey

如果我从我的Tampermonkey脚本中检查<input type="password"/>,并使用change处理程序查看由Chrome的密码管理器功能填充的密码字段的更改,则值保持为空,直到我执行在页面中进行真正的点击。我已经尝试在我的脚本中点击页面,但Chrome知道这不是真正的点击。当我在页面中进行物理点击时,change事件会突然触发,密码字段会获得一个值,然后我的脚本会做出正确的反应(由于有change事件)。但是我编写了这个脚本以避免首先与页面进行交互,因此这违背了我的脚本。

有没有办法让TamperMonkey将页面标记为让用户与其进行交互(例如,某些假设的GM_setUserTouched()GM_autoFillPasswords() API),以便密码管理器功能实际填充{ {1}}而不要求我点击页面?

背景

在Chrome中,#352527 comment 15 where it is unexpected behavior to the reporter#398805 where there is a case that Chrome fails to implement the behavior I don’t want中记录了此行为。当自动填充和Chrome的内置密码管理器填写表单时,会在密码字段中向用户显示密码字符,但DOM <input type="password"/>设置为HTMLInputElement.value。当用户与页面进行互动时,例如通过点击或按键,Chrome会修改""以包含密码,并在元素上触发HTMLInputElement.value事件。引用的原因是“安全性原因”(例如,如果网站脚本是从密码元素中读取的,那么只有在用户查看页面时才有机会这样做...所以popunders或不可见的框架是不是能够做到这一点?我不确定这会保护你什么:一旦用户与页面交互,所有脚本都可以访问密码。如果坏脚本是与change来源相同,网站本身存在安全漏洞,而不是Chrome ...... )。

Greasemonkey历史上有helper APIs<input type="password"/>系统,使用户可以解决此类问题。编辑:在创建repro时(下面),我发现Firefox使自动填充密码可供DOM使用,而无需等待用户与窗口进行交互。因此,Greasemonkey不需要@grant API,因为Firefox没有展示这个Chrome怪癖。因此,Tampermonkey没有这样的API。

摄制

因为当我描述Chrome所展示的行为时,人们不相信我,所以我准备了一个复制品。要让Chrome进入一个不认为用户已经与该页面进行过互动的状态需要一些工作,但您应该能够看到我使用这些步骤看到的内容:

  1. 打开Chrome。我在Windows 10上使用64位Chrome 61.0.3163.91。
  2. 导航至https://fiddle.jshell.net/xqfynp3e/22/show/light/
  3. 输入一些虚假的用户名和密码,然后按Enter键或单击按钮。 Chrome会提示您保存密码。
  4. 保存密码。
  5. 打开开发人员工具。
  6. 将其输入控制台(导航到页面而不会意外地与其进行交互):GM_forceAutofill()
  7. 在控制台中运行window.location.href = 'https://fiddle.jshell.net/xqfynp3e/22/show/light/?1'
  8. 观察the form’s password appears to be filled in visually and yet reading the DOM element in Console yields ""
  9. 点击文档。
  10. 再次在控制台中运行document.querySelector('input[type=password]').value
  11. 观察the form’s password hasn’t changed appearance and yet reading the DOM element in Console yields the bogus password you saved
  12. 我的问题,重申:我怎样才能让Tampermonkey执行“点击文档”步骤?如何告知Chrome与我的网页互动的密码自动填充功能,而不实际与网页进行实际交互?

    编辑:我找到了一种在Chrome中安全存储密码并使用Credentials Web API的静默中介支持通过用户脚本访问密码的替代方法:https://imgur.com/a/ts2W1

1 个答案:

答案 0 :(得分:3)

您无法使用Google的内置密码存储执行此操作,因为正如您所说, Chrome需要用户互动以启用此类密码 - 作为安全功能。

具体而言,Chrome需要将isTrusted属性设置为true的事件。 Tampermonkey无法解决此问题,因为even Chrome extensions are not able to set the isTrusted property

另见this related feature request from 2015

一种解决方案是使用密码管理器来填充这些字段,而无需使用Google的内置存储空间 有许多可用的,具有不同程度的跨设备和跨浏览器的支持。

或者您可以编写自己的Tampermonkey脚本来填写这些字段,无论Chrome存储了什么。

如果您确实编写了Tampermonkey脚本,我建议您使用a secure storage framework,不要将登录信息硬编码到脚本中。