If users can upload or share documents, a file can be crafted to attack your editor. Fabric.js JSON security matters because Fabric.js copies every key of a saved object onto the object it creates. The engine checks every document before Fabric.js sees it.
What is checked by default
- Prototype pollution. Keys named
__proto__,constructororprototypeare removed first, so they cannot change an object's prototype. - Unsafe image URLs. Each image URL is checked after
assets.resolveUrland before anything is fetched.http:,https:,blob:, relative addresses anddata:image/...are allowed.javascript:,file:and non-imagedata:addresses are refused withUNSAFE_DOCUMENT. - Size. A document with more than 50,000 objects, or nested more than 100 levels deep, is refused before loading, so a hostile file cannot freeze the tab.
- SVG export. Text is escaped, so a text box containing
<script>stays text.
Set your own limits
createDocumentEngine({
canvas,
limits: {
maxObjects: 10_000,
maxDepth: 40,
isAllowedUrl: (url) => url.startsWith("https://cdn.example.com/"),
},
history: { limit: 100, maxBytes: 32 * 1024 * 1024 },
});maxObjectssets the object limit, andmaxDepththe nesting limit.isAllowedUrlreplaces the default image URL rule. Only allow the hosts you serve images from.history.maxBytescaps the memory that undo history uses.
Check uploads on the server
The same checks run in Node without a canvas. Check files before you store them:
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;
}Good Fabric.js JSON security checks on both sides: in the browser before loading, and on the server before storing.
Reporting a security problem
Report security issues privately through GitHub security advisories on the package repository, not in a public issue.