运维刚生成一条数据库口令,点复制,切到终端粘贴——这半分钟里,口令同时存在于生成页、系统剪贴板,以及你接下来可能打开的每一个输入框。很多人只核对了前半段:生成有没有上传。另一篇写过怎么用 Network 核对明文没有离开浏览器。后半段经常被跳过:复制成功之后,还有谁能读到这块缓冲区。

本文不讲怎么生成高强度或可读密码,也不把「复制」写成产品功能清单。问题只有一个:口令进了剪贴板之后,还会被哪几类程序读走。MyPassGen 的复制按钮调用的是 navigator.clipboard.writeText,把字符串写进系统剪贴板;站内没有密码库,关闭标签页后服务器上不会留下这条口令。剪贴板却是操作系统的共享区,页面关了它还在。下面用规范、系统设置和能当场做的步骤把路径拆开。

先做一次分流

能交给密码管理器自动填充,就不要复制。必须复制时,只用一条不会上真实账户的测试口令做下面的核对;粘贴成功后立刻再复制一个无意义字符覆盖。发给远程同事时,走阅后即焚,而不是把明文长时间留在剪贴板或群聊里。

复制完成,秘密已经离开页面

生成页上的输入框属于当前标签页。剪贴板不属于任何标签页。MDN 把 Clipboard API 写成「异步读写系统剪贴板」:写入成功后,记事本、终端、聊天窗口、远程桌面,都能按各自的规则去读。HTTPS 只保护生成页到服务器的那条链路;它不保护你本机上的这块缓冲区。

旧接口 document.execCommand('copy') 已被标成不推荐,实现也不一致。新页面应使用 navigator.clipboard.writeText。这个写入本身通常不弹「是否允许读取」——Chromium 把 clipboard-write 视为可自动授予的写权限,Firefox 与 Safari 则要求最近有过一次用户手势(点按钮、按键),也就是规范里的瞬时激活。你点「复制」满足手势;脚本在后台默默写,在 Safari 上常会失败。这解释了「为什么有的页必须点一下才能复制」,不是站点在刁难。

MyPassGen 密码生成、阅后即焚链接、清洗结果的复制,都走同一条 writeText。打开即用,无需注册。复制成功只证明字符串进了系统剪贴板,不证明它几秒后会被谁读走,也不证明它不会出现在 Win+V 的历史列表里。把「已复制」四个字当成安全终点,漏掉的就是后面几条路径。

网页读取:权限和粘贴事件

网页想主动读剪贴板,走的是 navigator.clipboard.readText() 或 read()。规范要求安全上下文(HTTPS 或 localhost),并希望读取发生在用户刚刚操作过页面之后。浏览器落地并不统一,这正好可以当场试。

Chromium:clipboard-read 权限

Chrome、Edge 等在文档有焦点、但读取并不完全符合规范时,会申请 Permissions API 里的 clipboard-read。你点「允许」之后,权限会留下来:同一源的脚本以后可以再读,不必每次都弹窗。站点设置里可以查到「剪贴板」,也能撤回。嵌在别人页面里的 iframe 还要过 Permissions-Policy 的 clipboard-read / clipboard-write,父页没放行,子页调接口会失败。这是可以在开发者工具 Application → Permissions 里核对的事实,不是口号。

Firefox 与 Safari:临时粘贴菜单

Firefox 和 Safari 不打算实现这个持久权限。读取时若不符合规范、但仍有瞬时激活,会弹出一个短暂的上下文菜单,只有一项「粘贴」,大约一秒后才可点。同源内容有时可免这一步;跨源内容一般不能免。你没有点那一项,脚本拿不到文本。和 Chromium「允许一次、以后还能读」不是同一套模型。

你自己粘贴时:页面必然能读到

按 Ctrl+V / Cmd+V,或点输入框的「粘贴」,会触发 paste 事件。处理函数可以从 clipboardData 取出文本——这是你主动交给当前页的,不是后台偷读。风险在于:焦点在聊天窗口、工单回复框或错误的浏览器配置页时,手比眼睛快。剪贴板不会问「你是不是要贴口令」。

手机上还有另一层。iOS 14 起,应用在后台读取剪贴板时会在顶部闪一条横幅。iOS 16 起,应用若不用系统粘贴菜单、快捷键或 UIPasteControl,而是直接读 UIPasteboard,系统会先问「是否允许粘贴」。横幅和弹窗证明「有人在读」,不能证明「没有人读过」——你没看见,只说明这次没触发,或你点过允许。

不要把刚复制的口令再贴进会上传原文的检测页

有的「密码泄露查询」会把口令原文 POST 出去。剪贴板泄漏是本机路径;贴进会上传的网站是另一条出站路径。差别见本机对照泄露名单,和全网密码查询差在哪。本机检测只下载公开弱口令名单,待测密码留在输入框。生成和检测都打开即用,无需注册。

系统历史和云同步

网页权限只覆盖「当前标签页的脚本」。操作系统自己还维护一份历史,并且可能同步到别的设备。这两条不经过 clipboard-read 弹窗。

Windows 10 / 11 打开剪贴板历史后,用 Win+V 能看到最近复制的条目。微软说明:最多25 条;未固定的条目在重启后清空,固定的会留下。设置里还可以打开「跨设备同步」:同一微软账户登录的电脑之间同步文本。口令一旦进了历史,坐在这台电脑前的人、以及同步目标设备上的人,都能在面板里看见明文。固定(pin)尤其危险:重启也清不掉。

苹果的通用剪贴板走 Handoff:设备靠近、同一 Apple 账户、蓝牙和 Wi-Fi 打开、Handoff 开启(默认开)。在一台设备上复制,附近另一台可以粘贴;内容只留一小段时间,或直到任一侧复制了新内容。Apple 安全指南写得更直:应用可以在用户尚未粘贴时就访问剪贴板数据;开了通用剪贴板之后,这种访问会延伸到同一 iCloud 账户下的其他设备。加密用的是与 Handoff 相同的通道(BLE 4.2 配对、256 位 AES 密钥、广告用 AES-256-GCM),防的是路人窃听,不是「旁边那台已登录的 iPhone 读不到」。

密码管理器承认剪贴板是短暂暴露窗口。1Password 默认约 90 秒后清除复制内容,可在安全设置里关掉。Bitwarden 在桌面端、移动端和浏览器扩展里提供「清除剪贴板」,间隔从约 10 秒到 5 分钟,也可以设为从不。浏览器里的生成页通常不会替你做这件事:MyPassGen 复制成功后不会倒计时清空。覆盖要靠你自己再复制别的东西,或用系统面板清除。

远程桌面、扩展和误粘贴

远程桌面、VNC、许多会议软件默认把剪贴板双向重定向:你在远开会话里复制,本机也能贴;本机复制,对端也能贴。口令会同时出现在两台机器的缓冲区里。共享屏幕时,终端里刚贴上去的字符还可能被会议录像或截图留下。这和「网页有没有上传」是不同的层,Network 面板看不见。

浏览器扩展若申请了 clipboardRead / clipboardWrite(或 Chromium 的对应主机权限),可以在页面脚本的权限模型之外读写剪贴板。扩展商店的权限列表能核对;装了「剪贴板增强」「跨设备粘贴」类扩展,等于又开了一条同步通道。不要只看生成页有没有上传,也要看扩展列表。

最常见、也最容易当场复现的,仍是误粘贴:焦点在 Slack、邮件正文或工单回复里,手指按了粘贴。聊天记录、邮件归档、工单系统会把明文留下,保存时间远长于剪贴板的 90 秒。一次性把口令交给远程同事时,应走阅后即焚:密钥放在网址的 # 后面,阅读页无需登录;不要把同一条明文既复制进剪贴板,又贴进群。

对照表:五条泄漏路径

同一条刚复制的测试口令,至少能分成五条路径。差别不在算法名字,而在谁能读、你能不能当场看见。

路径 谁能读 你怎么当场看见
网页 readText() 拿到读权限或通过粘贴菜单的源 Chromium 权限弹窗;Firefox / Safari 的粘贴项
你自己的粘贴 当前焦点所在的页面或应用 输入框里出现明文;paste 事件
系统历史 / 云同步 本机用户;同步目标设备 Win+V;另一台 Apple 设备上的粘贴
远程桌面 / 会议 两端会话、录像、截图 对端记事本能否贴出;会议回放
扩展与管理器 声明了剪贴板权限的扩展 扩展权限页;管理器是否在 N 秒后清空

生成页用 Web Crypto 算出随机串、并且 Network 里没有口令正文,只关掉了「上传」这一条。上表另外四条仍然开着。能交给管理器自动填充时,根本不必经过剪贴板;必须手输或必须复制时,把暴露窗口压到「贴完立刻覆盖」这一步。

当场核对

下面这组步骤不依赖任何品牌承诺。用一条不会用于真实账户的口令做,例如生成器默认 16 位随机串。不要拿正在用的主密码练手。

  1. 打开生成页,生成一条测试口令,点复制。不要用于登录。打开开发者工具 Network,勾选「保留日志」,确认复制动作之后请求体和分析事件里没有这串字符。核对上传的方法见浏览器里做加密,怎么当场核对明文没有上传。
  2. 打开记事本或任意文本框,粘贴一次,确认剪贴板里就是刚才那串。再复制一个单字符 x,再贴一次:应变成 x,说明覆盖生效。
  3. 若在 Windows 且已打开剪贴板历史,按 Win+V。历史里应能看到刚才的测试口令;若已覆盖,最新一条应是 x,口令可能还留在更下面。不要点固定。用「全部清除」或继续复制无意义文本,直到列表里看不见口令。
  4. 打开一个空白标签页的控制台,执行 navigator.clipboard.readText().then(console.log, console.error)。Chromium 应弹出读权限或失败;Firefox / Safari 应出现粘贴项或拒绝。不要点「允许」来「方便调试」——允许等于给这个源留下持久读权。
  5. 有第二台登录了同一 Apple 账户或微软账户、并打开了同步的设备时,在那台设备上粘贴。若贴出测试口令,说明云同步或通用剪贴板已把明文送过去。关同步、关 Handoff,或等它超时后再试一次。
  6. 看已装扩展的权限列表,有没有剪贴板读写。远程桌面若开着,在对端记事本里试一次粘贴,确认重定向是否开启。

MyPassGen 的密码生成器按这个边界工作:随机模式 6–128 位,默认 16,低于 8 位会提示较弱;两种模式都用 getRandomValues 在当前标签页抽取;复制走 writeText。打开即用,无账号、无密码库。你要核对的是权限弹窗、Win+V 和另一台设备上的粘贴,不是页面上的「已复制」。

粘贴之后怎么收尾

今天必须复制的那一条,按这条顺序收尾:先确认焦点在正确的密码框,再粘贴;立刻复制一个无意义字符或用系统面板清除历史;需要发给别人时,改走阅后即焚,密钥放在 # 后面,不要把明文再留在剪贴板当「备份」。能改用管理器自动填充的账户,把复制从流程里删掉。

共享电脑、演示机、开着远程桌面的运维跳板,默认当作「剪贴板会被第二个人读」。这些环境上不要复制主密码。必须手输时,用更长的可读口令降低敲错率,并在用完后改掉——四个单词在 100 词表上大约只有 27 bits,不够当主密码,对照见随机密码和可读密码该怎么选。

做完「贴完覆盖」和「不要点允许读取」,你就已经能回答本文的问题:复制之后谁还能读,取决于网页权限、系统历史、云同步、远程会话和你自己的下一次粘贴。生成页不上传,只说明服务器日志里没有这串字符,并不收回操作系统已经发出去的那一份。

常见问题

HTTPS 是不是已经保证复制后的密码安全?

不是。HTTPS 保护的是浏览器到服务器的传输。剪贴板在本机,不走这条 TLS。网页上传、系统历史、通用剪贴板和误粘贴,都不看地址栏有没有锁形图标。

点了「允许读取剪贴板」,以后还能撤回吗?

在 Chromium 可以:站点设置 → 权限 → 剪贴板,改为阻止。Firefox 与 Safari 通常不把这次读取记成持久权限,下一次仍要经过粘贴项。不要为了少点一次就给不信任的源开读权。

生成密码需要注册吗?复制会不会上传?

不需要注册。生成和复制都应留在当前标签页。复制把字符串写入系统剪贴板,不是 POST 到服务器。打开 Network:复制之后,请求体和分析事件里不应出现那串密码。需要留给同事时,用阅后即焚,不要依赖剪贴板当传输通道。

密码管理器自动填充是不是比复制更安全?

对「少一次系统剪贴板暴露」来说,是。自动填充把口令送进当前表单,不经过 Win+V 那份历史。管理器若仍提供「复制」,那一次复制和生成页的复制走的是同一块缓冲区,仍然要覆盖。选得了自动填充,就不要复制。