剪贴内容无法离开这台电脑
整个程序中只有一个文件 net.py 可以建立连接,而它唯一的函数 get_json(url, allowed) 没有任何可以携带请求正文的参数。不存在上传剪贴内容的代码路径,因为根本没有可用来上传的东西。
每次推送时由 scripts/check_network.py 强制检查:只要其他模块导入网络库,或网关新增了 data、body、payload、content 或 text 参数,构建就会失败。
这些不是需要有人记住的方针:每一项都由一项检查或测试把守,违反就会让构建失败。
整个程序中只有一个文件 net.py 可以建立连接,而它唯一的函数 get_json(url, allowed) 没有任何可以携带请求正文的参数。不存在上传剪贴内容的代码路径,因为根本没有可用来上传的东西。
每次推送时由 scripts/check_network.py 强制检查:只要其他模块导入网络库,或网关新增了 data、body、payload、content 或 text 参数,构建就会失败。
程序没有使用统计、崩溃报告或分析功能。设置文件里还留着一个 telemetry 字段,但没有任何代码读取它来发送东西;而且每次加载或保存设置时,无论文件里写的是什么,Config.normalize() 都会把它强制设为 false。
src/clipvault/config.py — 每次加载和保存都经过 normalize()。
全新安装时两者都是关闭的,ClipVault 会在首次运行时询问。选择否,它就从不建立连接。选择是,它每天对一个小小的版本文件发出一次 HTTPS GET — 没有正文,没有 Cookie,没有标识符;它添加的唯一请求头只写明 ClipVault 及其版本。明文 HTTP 和重定向一律拒绝,超过 64 KB 的响应直接丢弃。
net.get_json、updates.fetch。组织可以通过 DisableUpdateCheck 和 DisablePromos 策略将两者关闭。
版本文件是程序获取来的东西,而不是它信任的东西。其中的链接只有在是 ClipVault 网站上的路径,或同一主机上的 https 地址时才会保留,因此被篡改的文件无法把您引向仿冒的下载。版本号只接受数字和点,所以也无法夹带消息。
updates.official_link、updates.clean_version — 对缓存的副本同样适用。
上方框内的一切都发生在您的电脑上、在您的 Windows 账号之下。下方框是程序唯一的网络路径,它接触不到您的剪贴内容。
关卡。被其应用标记为“不要记录”的剪贴内容 — 即 KeePass、1Password 和 Bitwarden 设置的标准标记 — 根本不会被读取。来自排除应用的剪贴内容会在保存前被丢弃;默认名单涵盖密码管理器和韩国的银行安全模块。组织策略可以添加应用,并关闭图片或文件的捕获。win/clipboard.read、Vault._gate
失败即关闭(fail-closed)的加密。凭据用 Windows DPAPI 加密并移除其文本,因此永远不会进入搜索索引。如果 DPAPI 不可用或加密失败,该剪贴内容会被丢弃,而不是以明文保留。Vault._protect
存储。首次运行时,文件夹停止继承权限,并显式授予您的账号访问权,因此上级文件夹的变动无法放宽它。凭据用带密钥的哈希去重,因此数据库中不含可被猜出值的指纹。win/acl.harden_once、Vault._dedupe_key
粘贴。ClipVault 会把焦点还给您原来的窗口,并在发送 Ctrl+V 之前再次确认它位于前台。如果无法确认,它什么都不发送,剪贴内容会留在剪贴板上等您处理。它放到剪贴板上的凭据本身就带有“不要记录”标记,因此 Windows 剪贴板历史和其他剪贴板管理器会跳过它。actions.deliver、win/exclusions.exclusion_payloads
清除。粘贴凭据后,剪贴板默认会在 30 秒后清空 — 但前提是这期间没有复制新内容。actions.clear_if_unchanged
网络。请求由一个只接收地址和您的同意、别无其他参数的函数发出,因此任何剪贴数据都不在它能触及的范围内。它拒绝明文 HTTP 和重定向,并丢弃超过 64 KB 的响应。net.py、updates.fetch
本地程序可以让某些攻击变得更难,但无法让已被攻破的 Windows 账号变得安全;如果声称可以,只会让您依赖错误的东西。
这与程序在 管理控制台 → 安全 中说明的边界相同:加密保证的是单凭数据库文件无法读取,仅此而已。
检测只给剪贴内容加标签,从不删除。被标记为凭据的剪贴内容会被加密并遮住。只有当您或您所在组织的策略开启相应选项时,才会拒绝保存。
带值的标签 — “password:”、“密码:”、“contraseña=”等,涵盖本应用提供的全部十二种语言中表示“密码”的词,全角冒号也包括在内。还包括 scheme://user:password@host 形式的地址。
OpenAI、Anthropic、Stripe、GitHub、GitLab、npm、SendGrid、AWS、Slack 和 Google 的已知格式;api_key= 或 client_secret: 之类带标签的值;DB_PASSWORD= 之类的 .env 行;Azure 连接字符串中的密钥。
Slack 和 Discord 的 Webhook 地址,它们本身就是凭据。
PEM 私钥块。
以 eyJ 开头的三段 base64url。
通过 Luhn 校验的 13 到 19 位数字。0000 0000 0000 0000 之类的占位数字会被忽略。
会核对其中的日期和校验位。
标记为个人数据,但不加密:人们是有意复制它们的。
检测在每次复制时运行,所以一个缓慢的模式就会让快捷键卡住。每个模式中的每处重复都有上限;测试会输入 14 个对抗性样本,如果输入变为 4 倍时耗时增加超过 8 倍就判定失败 — 这正是灾难性回溯的特征。只扫描剪贴内容的前 1,000,000 个字符,程序保存的文本也从不超过它扫描的长度。
sensitive.DETECT_LIMIT、Config.normalize、tests/test_security.py
IT 部门可以通过组策略或 Intune 在 HKLM\SOFTWARE\Policies\ClipVault 下强制设置。计算机和用户两处策略键都会被读取,以更严格的值为准;标准用户对两者都没有写入权限。
部件越少,别人的代码能混进来的地方就越少。
scripts/check_stdlib_only.py 会读取每一条 import,发现任何其他依赖就让构建失败。scripts/check_network.py 把网络功能限制在 net.py 之内,并确保其中不会出现任何正文参数。ClipVault.exe 由 PROJECTTEAMFORYOU 通过 Azure Artifact Signing 签名。要核实,请右键单击该文件 → 属性 → 数字签名。配置了签名时,构建会拒绝以未签名状态完成,并且在文件离开构建机器之前会再次验证签名。
网站会统计下载次数,以便我们了解哪些文件被使用。它保存的是计数,而不是日志。
断点续传的下载和爬虫不计入,程序的更新检查也完全不计入 — 同意检查版本并不等于同意被统计。deploy/cloudflare/lib/downloads.js
我们自己广告的点击——无论是在本网站上,还是在您开启消息后程序中的消息里——都以同样方式计数:日期、广告和国家。程序绝不在弹出窗口中展示广告,也绝不展示其他任何人的广告。deploy/cloudflare/lib/ads.js
请通过电子邮件私下报告,以便在公开之前修复。
我们的目标是在 3 个工作日内确认收到报告,并与您商定修复方案和披露日期。这是目标,而非保证:ClipVault 由一个小团队开发。
clipvault-cli --version)和您的 Windows 版本请不要发送真实密码或他人的剪贴板数据,并且只在属于您自己的计算机和账号上进行测试。
我们没有付费的漏洞赏金计划。如果您愿意,我们会在发布说明中具名致谢。