当你推出用于展示 PDF、PPT 或发票的精致 UI 时,通常会关注美观、响应式以及加载时间。然而,常被忽视的是 文档如何从你的服务器传输到用户的浏览器。一次小小的失误就可能把本来稳固的应用变成数据泄露的入口。
在本指南中,我们将逐一讲解 七个以安全为核心的功能,帮助你在集成以隐私为先的文档查看器时直接嵌入这些能力。此清单面向希望在不增加不必要复杂度的前提下强化嵌入的前端工程师。
1. 文档流的端到端加密
为什么重要
即使通过 HTTPS 提供文件,原始文档仍可能被受损的浏览器扩展或在响应到达查看器之前读取的恶意脚本拦截。
如何实现
| 步骤 | 操作 |
|---|---|
| 服务器端加密 | 在存储或流式传输之前对文件进行加密(AES‑256‑GCM 是可靠的选择)。 |
| 传输安全 | 通过 TLS 1.3 传输加密的二进制块。 |
| 客户端解密 | 启动一个 Web Worker,接收加密流,在内存中解密,并将明文直接输送到查看器的画布。 |
| 切勿泄露密钥 | 将解密密钥保存在短期、由服务器生成的令牌中(参见特性 #4)。 |
等到查看器渲染时,文档始终未以明文形式出现在网络或主线程中。
2. 内容安全策略(CSP)白名单
风险
宽松的 CSP 让攻击者注入恶意脚本或加载恶意资源,从而读取查看器的画布数据。
关键要点
- ‘unsafe‑inline’ 和 ‘unsafe‑eval’ 脚本被禁止。
- 仅允许查看器的 CDN(或自托管的包)提供 JavaScript。
- 框架仅限于受信任的查看器域名。
严格的 CSP 能显著降低承载嵌入页面的攻击面。
3. 通过 iframe 沙盒实现同源隔离
为什么使用沙盒?
即使有 CSP,受损的页面仍可能尝试进入查看器的 DOM。隔离的 <iframe> 形成一个 安全笼子,宿主页面在未获明确授权前无法突破。
应避免的沙盒标志
allow-top-navigation– 防止查看器劫持顶层窗口。allow-popups– 阻止可能用于网络钓鱼的意外弹窗。
如果查看器需要与父页面通信(例如 UI 同步),请使用 postMessage 并进行显式的来源检查。
4. 基于令牌的访问控制
直接 URL 的问题
公开的静态 URL 让任何拥有链接的人永久下载文件。
因为令牌在服务器端签名,任何篡改都会使请求失效,查看器也会拒绝加载。
5. 水印与动态叠加层
目的
客户端动态水印在不修改原始文件的前提下增加责任追溯层。
实现技巧
- 在位于 PDF 页面之上的 canvas overlay 上渲染水印。
- 使用会话的电子邮件或随机 UUID,使每个查看器实例唯一。
- 使用简单的标志切换叠加层,以保持性能开销最小。
如果泄露的文档出现,嵌入的标识符可直接指向泄露源头。
6. 下载与打印限制
浏览器默认行为
大多数浏览器会提供右键上下文菜单,允许将画布保存为图片,从而等同于导出页面。
查看器能做和不能做的事情
文档查看器 SDK 可以隐藏工具栏中的导出操作,而 Doconut 功能目录列出了浏览器打印和 PDF 导出等能力,供你决定是否呈现。请根据所安装构建的文档检查选项名称,而不是依据本文等文章,因为配置键会随版本变化。
更重要的是,没有任何工具栏设置能够覆盖的部分。隐藏按钮只是工作流选择,而非访问控制。服务器仍必须对每页、缩略图、导出、下载和打印请求进行授权,因为这些端点可以直接调用。且一旦像素出现在屏幕上,截图、摄像头以及辅助工具就会存在;声称能够完全防止这些的查看器实际上并不能兑现。
7. 审计日志与事件钩子
可视性的价值
即便是最坚固的查看器也可能被滥用。记录谁在何时打开了哪个文档以及执行了哪些操作,可形成取证轨迹。
通过实时日志,你可以检测异常模式——例如单个用户在几秒内打开数十份机密 PDF——并触发警报或撤销权限。
结论
嵌入文档查看器是一项安全责任,而非仅仅是 UI 工作。文档流的端到端加密、严格的 内容安全策略、隔离的 iframe 沙盒、基于令牌的访问、动态水印、将导出限制视为 UX 而非保护手段以及审计日志,是将可防御的嵌入与不可防御的嵌入区分开的关键。
无论选择哪款查看器,这七项中的两项始终由你掌控:授权和审计。没有任何组件能够替你为租户做出这些决定。
准备好构建嵌入了吗?
- 从供应商官方文档开始,使用你所安装的版本。 对于 Doconut,文档位于 doconut.com — 包、设置指南和示例。将配置键从文章中复制是导致升级后集成失效的原因。
- 将七点检查清单放入 Pull‑Request 模板,确保安全审查在合并前完成,而不是在事故后才进行。
- 先测试负面场景: 其他租户的文档标识、已过期的会话、直接请求页面或导出端点。这些测试才能发现真实的安全漏洞。
