SECURITY
安全设计说明
2FA Secret能够持续生成验证码,应按长期凭据处理。本源码通过缩小攻击面来降低风险,但不能替代用户自身的设备安全。
核心设计
- 使用浏览器Web Crypto API完成HMAC计算,不调用远程生成接口。
- 不使用WordPress、PHP、数据库或用户账号系统。
- JavaScript和CSS全部自托管,不加载任何第三方资源。
- Nginx配置通过CSP设置
connect-src 'none',禁止脚本发起网络连接。 - 不通过查询参数接收Secret,避免进入浏览器历史和服务器日志。
- 离开页面时尽量覆盖内存中的Secret字节数组。
已知边界
- “浏览器本地计算”并不消除对页面交付链的信任:用户仍需信任服务器、反向代理和首次加载的同源JavaScript。
connect-src 'none'可以阻止常见脚本网络连接,但不能证明同源代码永远不会被替换,也不能替代源码审计和发布校验。- 遭到控制的浏览器扩展、恶意输入法、系统木马仍可能读取页面内容。
- 用户复制验证码后,验证码会短暂存在于系统剪贴板。
- JavaScript只能尽力覆盖部分字节数组,无法保证清除浏览器内部字符串副本、页面快照或Web Crypto内部对象。
- 部署者修改源码、加入统计脚本、开启边缘脚本注入或放宽CSP后,隐私承诺可能失效。
上线前检查
- 执行
npm test,确认通过RFC 4648 Base32、RFC 4226 HOTP截断和RFC 6238 TOTP测试向量。 - 强制HTTPS并检查证书链。
- 使用浏览器开发者工具确认页面没有Fetch、XHR、Beacon或WebSocket请求。
- 检查响应头中的CSP、Cache-Control、Referrer-Policy和X-Frame-Options。
- 若使用Cloudflare,关闭该子域名的Web Analytics自动注入、Zaraz自动注入、Rocket Loader和RUM,并设置缓存绕过。
- 对源码做版本留档并限制服务器写入权限。