原生 <input type="password"> 无防键盘劫持能力,明文始终驻留 DOM 和内存;禁用事件无效,autocomplete 属性仅影响自动填充;唯一有效措施是提交或失焦后立即清空 value,并依赖 HTTPS 与服务端防护。

原生 <input type="password"> 没有防键盘劫持能力,它不拦截、不加密、不隔离输入过程——所有按键事件(keydown、input)照常触发,明文始终驻留 DOM 和内存中。
为什么禁用 onkeydown/oninput 无法阻止键盘劫持
很多开发者试图加 onkeydown="return false" 或 addEventListener('keydown', e => e.preventDefault()) 来“锁住”密码框,但这完全无效:
- 浏览器允许页面监听事件,但不阻止底层输入引擎把字符写入
input.value - 恶意脚本只需监听
input事件或定时轮询element.value,就能实时捕获明文 - DevTools 的 Elements 面板双击
value属性、或执行console.log(input.value)仍可秒取 - 某些 Android WebView 或 Electron 应用甚至允许直接读取系统级输入缓冲区
autocomplete="current-password" 和 "new-password" 的真实作用
这两个属性不是安全开关,而是给密码管理器发的语义信号,影响的是自动填充行为,和防劫持无关:
-
autocomplete="current-password":登录页使用,告诉浏览器“这是已有账号的密码”,触发已保存密码的填充 -
autocomplete="new-password":注册/改密页使用,提示浏览器“别填旧值,可生成新密码”,部分管理器会主动弹出强密码建议 - 设成
autocomplete="off"基本被 Chrome/Firefox/Safari 忽略;设错大小写(如Current-Password)则完全失效 - 如果表单里没有配套的用户名字段(
autocomplete="username"或email),管理器可能根本识别不出上下文,自动填充失灵
真正能缓解键盘劫持的前端可控动作
你无法阻止劫持,但可以大幅提高攻击成本、缩短明文暴露窗口:
立即学习“前端免费学习笔记(深入)”;
- 提交后立即清空
input.value:input.value = '',避免 DevTools 内存快照残留 - 密码框失焦(
blur)时清空临时 state 变量(React/Vue 中尤其重要) - 禁用粘贴(
onpaste="return false")无意义——现代密码管理器用的是自动填充 API,不是模拟粘贴;且禁用会破坏无障碍支持 - 不要用
localStorage或sessionStorage缓存任何密码相关中间值,哪怕只是 hash 片段 - 若必须前端处理(如 WebAuthn fallback 场景),用
crypto.subtle.digest()做即时哈希,但绝不保留原始字符串变量,哈希后立刻input.value = ''
最易被忽略的一点:所有前端“防护”都建立在 JS 执行环境可信的前提下。一旦页面被 XSS 注入,type="password" 和你写的任何事件拦截都形同虚设——真正的防线只有 HTTPS + 服务端即时哈希 + 密码管理器协同设计。



















