☰
html-in-canvas 安全与隐私:哪些敏感信息不能画进Canvas?读回允许渲染(read-back-allowed)完整解读
2026/10/6 19:48:05 网站建设 项目流程

html-in-canvas 安全与隐私:哪些敏感信息不能画进Canvas?读回允许渲染(read-back-allowed)完整解读

【免费下载链接】html-in-canvas项目地址: https://gitcode.com/gh_mirrors/ht/html-in-canvas

html-in-canvas 是 Chromium 社区的一个开放提案,让 2D/3D<canvas>直接绘制带样式的 HTML 内容(核心 API 为drawElementImage)。本文面向新手,完整解读它的安全与隐私设计:哪些敏感信息绝不能画进 Canvas,以及 read-back-allowed(读回允许渲染)如何守住像素读回这道安全底线。

为什么"画进Canvas"是个安全敏感操作?

传统上,<canvas>里的像素一旦生成,网页脚本就能通过getImageData()等方法逐像素读回——而 WebGL/WebGPU 的像素读回更是"随时可用"。

html-in-canvas 让 DOM 内容变成 Canvas 像素,等于给脚本开了一条"像素级观测"通道。攻击者可能借此探测两条路:

  1. 像素读回:把画进 Canvas 的内容读回来逐像素分析;
  2. 时机侧信道:观察paint事件是否触发、何时触发,也能推断出画面上发生了什么。

所以设计的第一条铁律是:任何绘制元素快照的 API 和paint事件,绝不能泄露网页代码原本看不到的安全/隐私敏感信息。这个设计就叫read-back-allowed rendering(读回允许渲染)——既然读回总有可能发生,那就保证"画进去的东西不含秘密",读回自然无害。🔒

来源:README.md 的 "Read-back-allowed rendering" 一节。

敏感信息黑名单:这些内容不能画进 Canvas

#敏感信息风险原因
1跨源嵌入内容(<iframe>、<img>等)把其他站点的私有数据变成可读像素
2<url>跨源引用(background-image、clip-path)同上
3被跨源数据"污染"的<canvas>经典 tainted canvas 场景
4SVG 跨源引用(<use>、<pattern>、<feImage>)同上
5系统颜色、主题、偏好设置可用于设备/系统指纹识别
6拼写与语法检查标记暴露用户正在书写的内容
7已访问链接信息(visited)暴露浏览历史
8表单自动填充的待填入内容涉及姓名、卡号等个人数据
9字幕偏好、IME 候选窗与特殊排版暴露个性化设置与输入行为

⚠️ 还有一个容易被忽略的细节:子像素文字抗锯齿同样会被排除,因为它也可被用于指纹识别。

注意一个"部分放行":同源的<iframe>会正常绘制,但其中嵌套的跨源内容不会。

允许清单:这些信息"不算敏感"

有些信息虽然新出现在画布里,但设计文档明确判定它们不敏感——判断标准只有一条:作者代码本就能观察到的信息,才允许出现在画布上。

  • 🔍 页面内搜索(find-in-page)与 text-fragment 标记
  • 滚动条与表单控件的外观(浏览器中早已可被检测)
  • 光标闪烁频率(caret blink rate)
  • forced-colors(JS 本就能通过媒体查询读取)

侧信道也被堵住:不止像素,还有"刷新时机"

很多 API 只防"画出来",但 html-in-canvas 把invalidation(失效/重绘)通道也纳入了防线:paint事件的触发时机本身就是信息源——比如"某个敏感内容变了"就会多触发一次paint。设计上对敏感信息的剔除是渲染和失效判定同时生效的:不画它,也不会因为它的变化而多触发paint。

官方安全与隐私问卷(security-privacy-questionnaire.md)对关键问题的回答非常直接:

  • 不暴露新的安全信息,并尽量把新增隐私信息压到最低;
  • 渲染出的像素不允许出现 PII,跨源信息、已访问链接、拼写检查、自动填充预览一律不绘制;
  • 不引入跨会话持久化状态、不访问传感器、不新增脚本执行机制,隐私模式下行为无差异。

新手体验:如何在浏览器里试跑

  1. 使用 Chrome Canary,打开chrome://flags/#canvas-draw-element启用该特性;
  2. 参考 README.md 的最小示例,核心结构只有两行属性:
<canvas id="canvas" layoutsubtree> <form drawable id="form_element"> <input id="name"> </form> </canvas>

在paint事件里调用ctx.drawElementImage(form_element, 100, 0),表单就会被绘制进 Canvas——而上面黑名单里的内容,绘制时会自动被"隐形处理",无需你手动遮罩。

更多可运行的演示(均为仓库内示例):

  • 旋转复杂文本:Examples/complex-text.html
  • 多行标签饼图:Examples/pie-chart.html
  • 3D 立方体贴 HTML:Examples/webGL.html
  • 嵌套 drawable 元素:Examples/nested-sparkles.html
  • WebGPU 果冻滑块:Examples/webgpu-jelly-slider/

小结:三句话记住这套安全设计

  1. 画进去的,只限脚本本来就看得见的信息——read-back-allowed 的核心原则;
  2. 敏感信息在"渲染"和"失效触发"两个通道同时剔除,堵住像素读回与侧信道两条路;
  3. 用最少的信息换最大的功能:光标、焦点、滚动条等交互所需信息放行,系统偏好、浏览历史、跨源数据一律拦下。

对开发者而言,这套规则意味着你不用自己操心"哪些内容该遮罩",画布天生就是防泄漏的——这正是 html-in-canvas 最值得借鉴的安全设计。

【免费下载链接】html-in-canvas项目地址: https://gitcode.com/gh_mirrors/ht/html-in-canvas

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询