From d1577bf18f5f6609d4c48a41c9310c8753e53ac2 Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Tue, 7 Oct 2025 18:04:38 -0700 Subject: [PATCH] fix mask editor on cloud by allowing crossorigin on image data (#5957) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed cross-origin canvas taint [error](https://comfy-org.sentry.io/issues/6927234287/?referrer=slack¬ification_uuid=e2ac931f-c955-43a2-a345-76fa8b164504&alert_rule_id=16146009&alert_type=issue) in mask editor by adding CORS support to image loading. When images from different origins are drawn to canvas without CORS headers, browsers "taint" the canvas to prevent data extraction attacks. This breaks `getImageData()` calls with a SecurityError. The [W3C standard solution](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/crossOrigin) is `crossOrigin = 'anonymous'`. Intended flow: 1. Frontend sets img.crossOrigin = 'anonymous' 2. Browser sends CORS preflight to GCS: "Can cloud.comfy.org access this image?" 3. GCS must respond: "Yes, that origin is allowed" 4. Browser loads image with CORS headers enabled 5. Canvas operations work without taint Canvas security model compliance and compatibility with cloud deployment image redirects to GCS. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5957-fix-mask-editor-on-cloud-by-allowing-crossorigin-on-image-data-2856d73d3650819a84b2fed19d85d815) by [Unito](https://www.unito.io) --- src/extensions/core/maskeditor.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/extensions/core/maskeditor.ts b/src/extensions/core/maskeditor.ts index af97c1340..436524633 100644 --- a/src/extensions/core/maskeditor.ts +++ b/src/extensions/core/maskeditor.ts @@ -1223,6 +1223,7 @@ class MaskEditorDialog extends ComfyDialog { // Create and set new image const newImage = new Image() newImage.src = mkFileUrl({ ref: actualFilepath, preview: true }) + newImage.crossOrigin = 'anonymous' ComfyApp.clipspace.imgs[paintedIndex] = newImage // Update images array - create if it doesn't exist @@ -1275,6 +1276,7 @@ class MaskEditorDialog extends ComfyDialog { // Create and set new image const newImage = new Image() newImage.src = mkFileUrl({ ref: actualFilepath, preview: true }) + newImage.crossOrigin = 'anonymous' ComfyApp.clipspace.imgs[indexToSaveTo] = newImage // Update images array - create if it doesn't exist @@ -4291,6 +4293,7 @@ class UIManager { this.image = await new Promise((resolve, reject) => { const img = new Image() + img.crossOrigin = 'anonymous' img.onload = () => resolve(img) img.onerror = reject img.src = rgb_url.toString() @@ -4302,6 +4305,7 @@ class UIManager { this.paint_image = await new Promise( (resolve, reject) => { const img = new Image() + img.crossOrigin = 'anonymous' img.onload = () => resolve(img) img.onerror = reject img.src = paintURL.toString() @@ -4437,6 +4441,7 @@ class UIManager { private loadImage(imagePath: URL): Promise { return new Promise((resolve, reject) => { const image = new Image() as HTMLImageElement + image.crossOrigin = 'anonymous' image.onload = function () { resolve(image) }