diff --git a/glob/manager_core.py b/glob/manager_core.py index 5ca569b8..fdea0697 100644 --- a/glob/manager_core.py +++ b/glob/manager_core.py @@ -43,7 +43,7 @@ import manager_downloader from node_package import InstalledNodePackage -version_code = [3, 30, 4] +version_code = [3, 30, 5] version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') @@ -53,6 +53,11 @@ DEFAULT_CHANNEL = "https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/ma default_custom_nodes_path = None +class InvalidChannel(Exception): + def __init__(self, channel): + self.channel = channel + super().__init__(channel) + def get_default_custom_nodes_path(): global default_custom_nodes_path if default_custom_nodes_path is None: @@ -251,6 +256,7 @@ comfy_ui_revision = "Unknown" comfy_ui_commit_datetime = datetime(1900, 1, 1, 0, 0, 0) channel_dict = None +valid_channels = set() channel_list = None @@ -355,7 +361,7 @@ def normalize_channel(channel): if channel_url: return channel_url - raise Exception(f"Invalid channel name '{channel}'") + raise InvalidChannel(channel) class ManagedResult: @@ -770,6 +776,11 @@ class UnifiedManager: print(f"[bold red]ERROR: Invalid mode is specified `--mode {mode}`[/bold red]", file=sys.stderr) return {} + # validate channel - only the channel set by the user is allowed. + if channel_url not in valid_channels: + logging.error(f'[ComfyUI-Manager] An invalid channel was used: {channel_url}') + raise InvalidChannel(channel_url) + json_obj = await get_data_by_mode(mode, 'custom-node-list.json', channel_url=channel_url) for x in json_obj['custom_nodes']: try: @@ -1414,7 +1425,11 @@ class UnifiedManager: version_spec = self.resolve_unspecified_version(node_id) if version_spec == 'unknown' or version_spec == 'nightly': - custom_nodes = await self.get_custom_nodes(channel, mode) + try: + custom_nodes = await self.get_custom_nodes(channel, mode) + except InvalidChannel as e: + return ManagedResult('fail').fail(f'Invalid channel is used: {e.channel}') + the_node = custom_nodes.get(node_id) if the_node is not None: if version_spec == 'unknown': @@ -1472,28 +1487,6 @@ class UnifiedManager: return res - async def migrate_unmanaged_nodes(self): - """ - fix path for nightly and unknown nodes of unmanaged nodes - """ - await self.reload('cache') - await self.get_custom_nodes('default', 'cache') - - print("Migration: STAGE 1") - moves = [] - - # migrate nightly inactive - for x, v in self.nightly_inactive_nodes.items(): - if v.endswith('@nightly'): - continue - - new_path = os.path.join(get_default_custom_nodes_path(), '.disabled', f"{x}@nightly") - moves.append((v, new_path)) - - self.reserve_migration(moves) - - print("DONE (Migration reserved)") - unified_manager = UnifiedManager() @@ -1565,6 +1558,7 @@ def get_installed_node_packs(): def get_channel_dict(): global channel_dict + global valid_channels if channel_dict is None: channel_dict = {} @@ -1578,6 +1572,7 @@ def get_channel_dict(): channel_info = x.split("::") if len(channel_info) == 2: channel_dict[channel_info[0]] = channel_info[1] + valid_channels.add(channel_info[1]) return channel_dict diff --git a/glob/manager_server.py b/glob/manager_server.py index 392d8424..5134ab35 100644 --- a/glob/manager_server.py +++ b/glob/manager_server.py @@ -399,7 +399,6 @@ async def task_worker(): try: node_spec = core.unified_manager.resolve_node_spec(node_spec_str) - if node_spec is None: logging.error(f"Cannot resolve install target: '{node_spec_str}'") return f"Cannot resolve install target: '{node_spec_str}'" @@ -929,6 +928,7 @@ def check_model_installed(json_obj): @routes.get("/externalmodel/getlist") async def fetch_externalmodel_list(request): + # The model list is only allowed in the default channel, yet. json_obj = await core.get_data_by_mode(request.rel_url.query["mode"], 'model-list.json') check_model_installed(json_obj) @@ -1197,9 +1197,8 @@ async def install_custom_node(request): git_url = None - if json_data['version'] != 'unknown': - selected_version = json_data.get('selected_version') - + selected_version = json_data.get('selected_version') + if json_data['version'] != 'unknown' and selected_version != 'unknown': if skip_post_install: if cnr_id in core.unified_manager.nightly_inactive_nodes or cnr_id in core.unified_manager.cnr_inactive_nodes: core.unified_manager.unified_enable(cnr_id) @@ -1216,6 +1215,9 @@ async def install_custom_node(request): if git_url is None: logging.error(f"[ComfyUI-Manager] Following node pack doesn't provide `nightly` version: ${git_url}") return web.Response(status=404, text=f"Following node pack doesn't provide `nightly` version: ${git_url}") + elif json_data['version'] != 'unknown' and selected_version == 'unknown': + logging.error(f"[ComfyUI-Manager] Invalid installation request: {json_data}") + return web.Response(status=400, text="Invalid installation request") else: # unknown unknown_name = os.path.basename(json_data['files'][0]) @@ -1407,17 +1409,13 @@ async def disable_node(request): return web.Response(status=200) -@routes.get("/manager/migrate_unmanaged_nodes") -async def migrate_unmanaged_nodes(request): - logging.info("[ComfyUI-Manager] Migrating unmanaged nodes...") - await core.unified_manager.migrate_unmanaged_nodes() - logging.info("Done.") - return web.Response(status=200) +async def check_whitelist_for_model(item): + json_obj = await core.get_data_by_mode('cache', 'model-list.json') - -@routes.get("/manager/need_to_migrate") -async def need_to_migrate(request): - return web.Response(text=str(core.need_to_migrate), status=200) + for x in json_obj.get('models', []): + return True + + return False @routes.post("/manager/queue/install_model") @@ -1428,6 +1426,11 @@ async def install_model(request): logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW) return web.Response(status=403, text="A security error has occurred. Please check the terminal logs") + # validate request + if not await check_whitelist_for_model(json_data): + logging.error(f"[ComfyUI-Manager] Invalid model install request is detected: {json_data}") + return web.Response(status=400, text="Invalid model install request is detected") + if not json_data['filename'].endswith('.safetensors') and not is_allowed_security_level('high'): models_json = await core.get_data_by_mode('cache', 'model-list.json', 'default') diff --git a/pyproject.toml b/pyproject.toml index 18bd18f7..cdac366e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-manager" description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI." -version = "3.30.4" +version = "3.30.5" license = { file = "LICENSE.txt" } dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions", "toml", "uv", "chardet"]