[GH-ISSUE #2998] (sec?): Two custom-node-list entries collide on lowercased repo basename (comfyui-ranbooru): installing one can fetch/satisfy the other #1078

Open
opened 2026-10-27 21:25:34 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @tyrypyrking on GitHub (Jun 15, 2026).
Original GitHub issue: https://github.com/Comfy-Org/ComfyUI-Manager/issues/2998

Two different node packs are registered in custom-node-list.json whose Git URL
basenames differ only by letter case:

- https://github.com/Inzaniak/comfyui-ranbooru      (the original Ranbooru node)
- https://github.com/liming123332/ComfyUI-Ranbooru  (an unrelated third-party fork)

Because package identity and the install folder are both derived from the
URL basename, and that key is lowercased, these two entries normalize to the
same identity ("comfyui-ranbooru"). The practical effect is that requesting one
package can install, or be satisfied by, the other — they are indistinguishable
to the Manager.

What I observed

Installing the Inzaniak package through ComfyUI-Manager resulted in the
liming123332 fork being present instead. The two are easy to tell apart on disk:

- Inzaniak (expected): has ranbooru.conf, assets/, English readme.md,
  nodes like PromptMix / PromptBackground / LockSeed
- liming123332 fork (got this): has install.py, scripts/ranbooru.py, a .trae/
  folder, a Chinese README.md, single node RanbooruPrompt

(I have not reproduced this in a clean environment, so I'm reporting the observed
behavior plus the code path that appears to explain it — happy to test a fix.)

This is likely to have security issues because it's fetching the latter package that could have malicious payloads or be generally unsound. My repro is on stable release, latest update.

Originally created by @tyrypyrking on GitHub (Jun 15, 2026). Original GitHub issue: https://github.com/Comfy-Org/ComfyUI-Manager/issues/2998 Two different node packs are registered in custom-node-list.json whose Git URL basenames differ only by letter case: - https://github.com/Inzaniak/comfyui-ranbooru (the original Ranbooru node) - https://github.com/liming123332/ComfyUI-Ranbooru (an unrelated third-party fork) Because package identity and the install folder are both derived from the URL basename, and that key is lowercased, these two entries normalize to the same identity ("comfyui-ranbooru"). The practical effect is that requesting one package can install, or be satisfied by, the other — they are indistinguishable to the Manager. ### What I observed Installing the Inzaniak package through ComfyUI-Manager resulted in the liming123332 fork being present instead. The two are easy to tell apart on disk: - Inzaniak (expected): has ranbooru.conf, assets/, English readme.md, nodes like PromptMix / PromptBackground / LockSeed - liming123332 fork (got this): has install.py, scripts/ranbooru.py, a .trae/ folder, a Chinese README.md, single node RanbooruPrompt (I have not reproduced this in a clean environment, so I'm reporting the observed behavior plus the code path that appears to explain it — happy to test a fix.) This is likely to have security issues because it's fetching the latter package that could have malicious payloads or be generally unsound. My repro is on stable release, latest update.
Author
Owner

@tyrypyrking commented on GitHub (Jun 15, 2026):

Some more additional info that could be of use:

Registry entries

Both are in custom-node-list.json on main:

{ "author": "Inzaniak", "id": "ranbooru",
  "reference": "https://github.com/Inzaniak/comfyui-ranbooru", ... }

{ "author": "liming123332", "title": "ComfyUI-Ranbooru",   (no "id" field)
  "reference": "https://github.com/liming123332/ComfyUI-Ranbooru", ... }

Note the fork entry has no "id" field, so it falls back to deriving identity
from the URL basename.

Likely mechanism (glob/manager_core.py, v3.40)

  1. Identity is taken from the last path segment of the Git URL:
    repo_name = y.split('/')[-1] # ~line 862
    node_id = v['files'][0].split('/')[-1] # ~line 908

    This yields "comfyui-ranbooru" vs "ComfyUI-Ranbooru".

  2. That key is lowercased in NormalizedKeyDict:
    def _normalize_key(self, key):
    if isinstance(key, str):
    return key.strip().lower() # ~line 411

    => both collapse to "comfyui-ranbooru".

  3. The install/clone target folder is also the URL basename, so on
    case-insensitive filesystems (Windows, default macOS) the two map to the
    same physical directory; on case-sensitive Linux they still collide on the
    lowercased identity key used for "is this installed?" tracking.

The net result: the "installed?" check for one package is satisfied by the
other, and the resolver can map an install request to the wrong folder.

Suggested fixes (any one helps)

- Key packages by their full normalized URL (owner + repo), not just the
  basename, so Inzaniak/comfyui-ranbooru and liming123332/ComfyUI-Ranbooru
  stay distinct.
- Detect and reject/flag list entries whose basenames collide under
  lowercasing when validating custom-node-list.json (CI lint).
- When deriving the on-disk folder, disambiguate colliding names (e.g.
  include the owner) instead of using a bare basename.
<!-- gh-comment-id:4711126211 --> @tyrypyrking commented on GitHub (Jun 15, 2026): Some more additional info that could be of use: ### Registry entries Both are in custom-node-list.json on main: { "author": "Inzaniak", "id": "ranbooru", "reference": "https://github.com/Inzaniak/comfyui-ranbooru", ... } { "author": "liming123332", "title": "ComfyUI-Ranbooru", (no "id" field) "reference": "https://github.com/liming123332/ComfyUI-Ranbooru", ... } Note the fork entry has no "id" field, so it falls back to deriving identity from the URL basename. ### Likely mechanism (glob/manager_core.py, v3.40) 1. Identity is taken from the last path segment of the Git URL: repo_name = y.split('/')[-1] # ~line 862 node_id = v['files'][0].split('/')[-1] # ~line 908 This yields "comfyui-ranbooru" vs "ComfyUI-Ranbooru". 2. That key is lowercased in NormalizedKeyDict: def _normalize_key(self, key): if isinstance(key, str): return key.strip().lower() # ~line 411 => both collapse to "comfyui-ranbooru". 3. The install/clone target folder is also the URL basename, so on case-insensitive filesystems (Windows, default macOS) the two map to the same physical directory; on case-sensitive Linux they still collide on the lowercased identity key used for "is this installed?" tracking. The net result: the "installed?" check for one package is satisfied by the other, and the resolver can map an install request to the wrong folder. ### Suggested fixes (any one helps) - Key packages by their full normalized URL (owner + repo), not just the basename, so Inzaniak/comfyui-ranbooru and liming123332/ComfyUI-Ranbooru stay distinct. - Detect and reject/flag list entries whose basenames collide under lowercasing when validating custom-node-list.json (CI lint). - When deriving the on-disk folder, disambiguate colliding names (e.g. include the owner) instead of using a bare basename.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/ComfyUI-Manager#1078
No description provided.