comfyanonymous / ComfyUI

The most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface.
https://www.comfy.org/
GNU General Public License v3.0
57.03k stars 6.04k forks source link

Potential CORS Regression w.r.t instances behind proxy #4865

Closed MoezGholami closed 2 months ago

MoezGholami commented 2 months ago

Expected Behavior

Running comfyui behind a proxy in Runpod without 403 errors

Actual Behavior

Context: running https://github.com/ai-dock/comfyui/ on Runpod. There, comfyui instance is put behind Cloudflare proxy. Today, after updating ComfyUI, I get 403 CORS errors when I attempt to run a prompt.

Steps to Reproduce

Put a comfyui instance behind a cloudflare, or just run https://github.com/ai-dock/comfyui/ somewhere.

Debug Logs

WARNING: request with non matching host and origin 100.65.18.228 != rr2bafdlplpwio-8188.proxy.runpod.net, returning 403

Other

I think these commits should be investigated: 3ab3516e46703376ebcb3d24a794e8405962398e , cbaac71bf55c55e0bb4b878708fddece35073122 , e3b0402bb792c528a8b2fadd11d35604bafc0d7b , e0b41243b413c841d84f2e85d7ba3e71382febf4

MoezGholami commented 2 months ago

mitigation: running comfyui with flag --enable-cors-header '*'

niko2020 commented 2 months ago

same problem for me

Kuvshin8 commented 2 months ago

Same problem on RunPod

PhoneHomePhone commented 2 months ago

Appears Commit [54fca4a] might be cause of the issue?

For Runpod running ComfyUI on port 3020:

  1. Replace lines 83-104 in server.py with code below.

  2. Replace "xxxxxxxxxxxxxx-3020.proxy.runpod.net", "XXX.XX.XX.XX" with the ip and pod address found in the error. IF: "WARNING: request with non matching host and origin 100.65.18.228 != rr2bafdlplpwio-8188.proxy.runpod.net, returning 403" Then: trusted_origins = ["rr2bafdlplpwio-8188.proxy.runpod.net", "100.65.18.228"]

  3. Save server.py

  4. Restart ComfyUI

def create_origin_only_middleware():
    @web.middleware
    async def origin_only_middleware(request: web.Request, handler):
        # Allow trusted origins
        trusted_origins = ["xxxxxxxxxxxxxx-3020.proxy.runpod.net", "XXX.XX.XX.XX"]

        if 'Host' in request.headers and 'Origin' in request.headers:
            host = request.headers['Host']
            origin = request.headers['Origin']
            host_domain = host.lower()
            parsed = urllib.parse.urlparse(origin)
            origin_domain = parsed.netloc.lower()

            # Debug log to see what is being checked
            logging.debug(f"Host domain: {host_domain}, Origin domain: {origin_domain}")

            # Strip ports if necessary
            if parsed.port is None:
                result = urllib.parse.urlsplit('//' + host_domain)
                host_domain = result.hostname
            host_domain_parsed = urllib.parse.urlsplit('//' + host_domain)
            if parsed.port is None:
                host_domain = host_domain_parsed.hostname
            if host_domain_parsed.port is None:
                origin_domain = parsed.hostname

            # Debug log to verify trusted origins
            logging.debug(f"Trusted origins: {trusted_origins}")
            logging.debug(f"Checking if {origin_domain} is in trusted origins.")

            # Allow trusted origins and skip the check
            if origin_domain in trusted_origins:
                logging.debug(f"Origin {origin_domain} is in trusted origins. Allowing request.")
                return await handler(request)

            # Otherwise, enforce the host-origin check
            if host_domain is not None and origin_domain is not None and len(host_domain) > 0 and len(origin_domain) > 0:
                if host_domain != origin_domain:
                    logging.warning("WARNING: request with non matching host and origin {} != {}, returning 403".format(host_domain, origin_domain))
                    return web.Response(status=403)

        # Allow OPTIONS requests (CORS preflight)
        if request.method == "OPTIONS":
            return web.Response(status=200)

        return await handler(request)  # Ensure 'await' is used inside an 'async' function

    return origin_only_middleware

This worked for me but I'm a CHATGPT DEV, noob, double check this please!

Trailblazingg commented 2 months ago

Still having the issue on Runpod I am using the: ComfyUI aitrepreneur/comfyui:2.3.5 template, when I try updating ComfyUI and restarting I get the same issue.

WARNING: request with non matching host and origin 100.65.18.228 != rr2bafdlplpwio-8188.proxy.runpod.net, returning 403

comfyanonymous commented 2 months ago

https://github.com/comfyanonymous/ComfyUI/commit/36c83cdbba89a01830816240553f16dd72377cd9

I relaxed the check a bit so it should work with reverse proxies now while still preventing the exploit.

Trailblazingg commented 2 months ago

36c83cd

I relaxed the check a bit so it should work with reverse proxies now while still preventing the exploit.

Seems good now Thanks!