Skip to content

Commit fe0eaae

Browse files
fix mask editor on cloud by allowing crossorigin on image data (#5957)
## Summary Fixed cross-origin canvas taint [error](https://comfy-org.sentry.io/issues/6927234287/?referrer=slack&notification_uuid=e2ac931f-c955-43a2-a345-76fa8b164504&alert_rule_id=16146009&alert_type=issue) in mask editor by adding CORS support to image loading. ## Background 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 ## Review Focus 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)
1 parent 99b3a59 commit fe0eaae

File tree

1 file changed

+5
-0
lines changed

1 file changed

+5
-0
lines changed

src/extensions/core/maskeditor.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,7 @@ class MaskEditorDialog extends ComfyDialog {
11681168
if (ComfyApp.clipspace?.imgs && paintedIndex !== undefined) {
11691169
// Create and set new image
11701170
const newImage = new Image()
1171+
newImage.crossOrigin = 'anonymous'
11711172
newImage.src = mkFileUrl({ ref: filepath, preview: true })
11721173
ComfyApp.clipspace.imgs[paintedIndex] = newImage
11731174

@@ -1209,6 +1210,7 @@ class MaskEditorDialog extends ComfyDialog {
12091210
if (!ComfyApp.clipspace?.imgs || indexToSaveTo === undefined) return
12101211
// Create and set new image
12111212
const newImage = new Image()
1213+
newImage.crossOrigin = 'anonymous'
12121214
newImage.src = mkFileUrl({ ref: filepath, preview: true })
12131215
ComfyApp.clipspace.imgs[indexToSaveTo] = newImage
12141216

@@ -4162,6 +4164,7 @@ class UIManager {
41624164

41634165
this.image = await new Promise<HTMLImageElement>((resolve, reject) => {
41644166
const img = new Image()
4167+
img.crossOrigin = 'anonymous'
41654168
img.onload = () => resolve(img)
41664169
img.onerror = reject
41674170
img.src = rgb_url.toString()
@@ -4173,6 +4176,7 @@ class UIManager {
41734176
this.paint_image = await new Promise<HTMLImageElement>(
41744177
(resolve, reject) => {
41754178
const img = new Image()
4179+
img.crossOrigin = 'anonymous'
41764180
img.onload = () => resolve(img)
41774181
img.onerror = reject
41784182
img.src = paintURL.toString()
@@ -4308,6 +4312,7 @@ class UIManager {
43084312
private loadImage(imagePath: URL): Promise<HTMLImageElement> {
43094313
return new Promise((resolve, reject) => {
43104314
const image = new Image() as HTMLImageElement
4315+
image.crossOrigin = 'anonymous'
43114316
image.onload = function () {
43124317
resolve(image)
43134318
}

0 commit comments

Comments
 (0)