# 安全

> 用户上传文档时的 Fabric.js JSON 安全：阻止原型污染，拒绝不安全的图片地址，在加载前限制对象数量。

Source: https://fabricjs-document-engine.jscrate.dev/zh/docs/guides/security
Last updated: 2026-09-28

如果用户可以上传或分享文档，就有人能专门构造文件来攻击你的编辑器。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>` 仍然只是文字。

## 设置你自己的限制

```ts
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 里无需画布也能运行。存储文件之前先检查：

```ts
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 安全，两边都要检查：浏览器里加载之前，服务器上存储之前。

## 报告安全问题

请通过 [代码仓库](https://github.com/re-sohail/fabricjs-document-engine) 的 GitHub security advisories 私下报告安全问题，不要发在公开的 issue 里。
