Fabric.js Document Engine

搜索文档

查找页面或章节

EN

文档常常来自用户,要把它们当作不可信的内容。

如果用户可以上传或分享文档,就有人能专门构造文件来攻击你的编辑器。Fabric.js JSON 安全之所以重要,是因为 Fabric.js 会把保存对象的每个键都复制到它创建的对象上。引擎会在 Fabric.js 看到文档之前检查每份文档。

默认检查的内容

  • 原型污染。 名为 __proto__、constructor 或 prototype 的键会先被删除,所以它们无法修改对象的原型。
  • 不安全的图片地址。 每个图片地址都会在 assets.resolveUrl 之后、发起任何请求之前检查。http:、https:、blob:、相对地址和 data:image/... 是允许的。javascript:、file: 和非图片的 data: 地址会以 UNSAFE_DOCUMENT 拒绝。
  • 大小。 超过 50,000 个对象或嵌套超过 100 层的文档,会在加载前被拒绝,恶意文件没法卡死标签页。
  • SVG 导出。 文字会被转义,所以文本框里的 <script> 仍然只是文字。

设置你自己的限制

createDocumentEngine({
  canvas,
  limits: {
    maxObjects: 10_000,
    maxDepth: 40,
    isAllowedUrl: (url) => url.startsWith("https://cdn.example.com/"),
  },
  history: { limit: 100, maxBytes: 32 * 1024 * 1024 },
});
  • maxObjects 限制对象数量,maxDepth 限制嵌套层数。
  • isAllowedUrl 替换默认的图片地址规则。只允许你提供图片的那些域名。
  • history.maxBytes 限制撤销历史占用的内存。

在服务器上检查上传

同样的检查在 Node 里无需画布也能运行。存储文件之前先检查:

import {
  migrateDocument,
  secureDocument,
  validateDocument,
} from "fabricjs-document-engine";
 
export function acceptUpload(body: unknown) {
  const safe = secureDocument(body, { maxObjects: 20000 });
  const { document } = migrateDocument(safe, {
    canvasWidth: 1200,
    canvasHeight: 800,
  });
  const issues = validateDocument(document);
  if (issues.length > 0) throw new Error("Invalid document");
  return document;
}

做好 Fabric.js JSON 安全,两边都要检查:浏览器里加载之前,服务器上存储之前。

报告安全问题

请通过 代码仓库 的 GitHub security advisories 私下报告安全问题,不要发在公开的 issue 里。