mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-06-20 23:09:20 +08:00
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
* feat(security): dedicated install flags decouple git_url/pip from security_level
Install via git URL and pip install are no longer gated by
security_level. Each surface gets a dedicated config.ini flag —
allow_git_url_install / allow_pip_install (both default false, secure
by default) — that fully REPLACES the security-level term for these two
features. The network-position invariant is retained: a non-local
listener stays denied regardless of the flags unless
network_mode = personal_cloud.
- New pure predicate is_dedicated_install_allowed() in
common/manager_security (no config access; callers resolve config)
- Legacy endpoints /v2/customnode/install/git_url and .../pip switch
from is_allowed_security_level('high+') to the flag gate; batch
installs of unknown git URLs likewise (middle+ entry gate unchanged,
unknown-pip 'block' stays unconditional; response shapes preserved)
- Config readers/writers (glob + legacy) parse and persist the flags;
denial logs and frontend 403 messages name the responsible flag and
note the non-local-listener requirement (network_mode=personal_cloud)
- No auto-seed from security_level — users previously on weak/normal-
must opt in explicitly (see CHANGELOG migration notes; README
documents the new contract)
- Update the pre-existing permissive E2E harness
(start_comfyui_permissive.sh + test_e2e_legacy_real_ops.py) to the
new contract: it now also sets allow_git_url_install /
allow_pip_install = true, since security_level = normal- alone no
longer opens the git_url/pip endpoints
Tests: predicate truth table proving security_level independence in
both directions, dual-reader config contract, security-level-matrix
freeze guards, legacy gate regression guards (121 unit), plus 22
real-server E2E tests incl. URL-form pip install with self-clean.
* test(e2e): fix fresh-env failures in customnode_info and git_clone harnesses
Two pre-existing harness defects that fail deterministically on a fresh
E2E environment (unrelated to the dedicated-install-flags change):
- test_e2e_customnode_info: TestInstalledPacks asserted the seed pack
ComfyUI_SigmoidOffsetScheduler is installed, but nothing seeded it —
the installing module (test_e2e_endpoint) runs alphabetically later
and uninstalls it at the end. Add a module-scoped autouse fixture
that installs the pack via cm-cli BEFORE the server starts (the
imported-mode test asserts against the startup-frozen snapshot, so
API-based seeding after boot cannot work) and removes it on teardown
only if the fixture installed it.
- test_e2e_git_clone: _ensure_cache ran cm-cli update-cache with a
120s timeout; the full DB download routinely exceeds that on slow
links, erroring the whole module at setup. Raise to 600s.
Verified from a fresh state (seed pack absent): both modules pass
(13 tests, incl. previously-failing TestInstalledPacks 2 and
TestNightlyInstallCycle 3).
155 lines
8.2 KiB
Markdown
155 lines
8.2 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to **ComfyUI-Manager** are documented in this file.
|
|
|
|
The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/),
|
|
and this project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
|
|
|
|
## [Unreleased]
|
|
|
|
### Security
|
|
|
|
- **Dedicated install flags decouple git-URL / pip installs from `security_level`**:
|
|
`POST /v2/customnode/install/git_url` and `POST /v2/customnode/install/pip`
|
|
(and the batch install path for git URLs not in the custom-node DB) are now
|
|
gated by two new `config.ini` `[default]` flags — `allow_git_url_install`
|
|
and `allow_pip_install` — instead of `security_level`. Both default to
|
|
`false` (secure by default), and a non-loopback listener stays denied unless
|
|
`network_mode = personal_cloud` (the existing network-position invariant is
|
|
retained — the flags never widen exposure beyond what was possible before).
|
|
`security_level` no longer has any effect on these two endpoints, in either
|
|
direction. The unknown-pip-package block in batch installs remains
|
|
unconditional. Activation requires a restart (no hot reload).
|
|
|
|
### Migration notes
|
|
|
|
- **Users running `security_level = weak` or `normal-`**: these environments
|
|
could previously use the git-URL / pip install endpoints; after upgrading
|
|
they are denied (HTTP 403) until you explicitly opt in by setting
|
|
`allow_git_url_install = true` and/or `allow_pip_install = true` in the
|
|
`[default]` section of `config.ini`. The flags are NOT auto-seeded from
|
|
your `security_level` — explicit opt-in is intentional.
|
|
|
|
## [4.2.1] - 2026-04-22
|
|
|
|
Security-hardening release. Contains breaking-ish API changes for
|
|
state-mutating endpoints. See **Migration notes** below before upgrading
|
|
programmatic clients.
|
|
|
|
### Security
|
|
|
|
- **CSRF Content-Type gate**: 18 state-mutation POST handlers (9 in `glob`, 9 in
|
|
`legacy`) now reject the three CORS "simple request" Content-Types
|
|
(`application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`).
|
|
This closes the residual `<form method="POST">` bypass route that remained
|
|
after the GET→POST transition. Legitimate clients using `application/json`
|
|
(or no body) are unaffected.
|
|
- **`do_fix` security level raised from `high` to `high+`**: aligns the
|
|
enforcement gate (`is_allowed_security_level`) with the log text emitted by
|
|
`SECURITY_MESSAGE_HIGH_P`. Both `glob/manager_server.py` and
|
|
`legacy/manager_server.py` updated in lockstep. Environments running at
|
|
`security_level = high` can no longer fix a nodepack — use
|
|
`security_level = normal` or lower.
|
|
- **Config setters now gated at `middle` security level**:
|
|
`POST /v2/manager/db_mode`, `POST /v2/manager/policy/update`, and
|
|
`POST /v2/manager/channel_url_list` now check
|
|
`is_allowed_security_level('middle')` before mutating configuration (both
|
|
`glob` and `legacy`). Closes a pre-existing gap where the write path was
|
|
reachable at any security level. Reads (`GET`) remain unrestricted.
|
|
|
|
### Changed
|
|
|
|
- **State-changing endpoints converted from `GET` to `POST`** (CSRF hardening):
|
|
`/v2/manager/queue/{update_all, reset, start, update_comfyui}`,
|
|
`/v2/snapshot/{remove, restore, save}`,
|
|
`/v2/comfyui_manager/comfyui_switch_version`,
|
|
`/v2/manager/reboot`.
|
|
Query-string parameters are preserved where they existed; only the HTTP
|
|
method changes.
|
|
- **`POST /v2/comfyui_manager/comfyui_switch_version` parameters moved from
|
|
query string to JSON body** (REST idiom + body-reading CSRF posture):
|
|
The handler now consumes `application/json` with the body shape
|
|
`{"ver": "...", "client_id": "...", "ui_id": "..."}` instead of reading
|
|
`?ver=...&client_id=...&ui_id=...` from the URL. Because body-reading
|
|
handlers are already covered by the CORS-preflight mechanism for
|
|
cross-origin protection, the Content-Type rejection gate introduced for
|
|
the other state-mutation endpoints is intentionally NOT applied here
|
|
(see `comfyui_manager/common/manager_security.py` module docstring).
|
|
The first-party JS client in `comfyui_manager/js/comfyui-manager.js`
|
|
was updated in the same change; third-party callers must migrate.
|
|
- **Config endpoints split into `GET` (read) + `POST` (write)**:
|
|
`/v2/manager/{db_mode, policy/update, channel_url_list}`. `GET` returns the
|
|
current value; `POST` accepts a JSON body `{"value": "..."}`. The prior
|
|
single-method form that accepted a `?value=...` query parameter on either
|
|
verb is retired.
|
|
- **`openapi.yaml` fully resynchronized** with the server: HTTP methods, the
|
|
dual-method splits above, request-body schemas for the new POST setters,
|
|
and the `TaskHistoryItem.params` field now match `manager_server.py`.
|
|
- **Legacy `restart(self)` → `restart(request)`**: parameter name corrected.
|
|
No behavioral change.
|
|
|
|
### Added
|
|
|
|
- **Server-push feature flag `extension.manager.supports_csrf_post`** registered
|
|
at startup, allowing ComfyUI-frontend (and other clients) to detect
|
|
CSRF-POST backend support as a semantic capability contract, without
|
|
relying on version string parsing. Manager versions prior to 4.2.1 do not
|
|
set the flag — clients should treat its absence as 'incompatible with
|
|
POST-only state-mutation endpoints'.
|
|
- **E2E test harness variants** for security-level and legacy-mode scenarios:
|
|
`tests/e2e/scripts/start_comfyui_legacy.sh`,
|
|
`tests/e2e/scripts/start_comfyui_permissive.sh`,
|
|
`tests/e2e/scripts/start_comfyui_strict.sh`. See
|
|
`docs/guide/GUIDE_E2E_TEST.md` for usage.
|
|
- **`COMFYUI_MANAGER_SKIP_MANAGER_REQUIREMENTS` environment variable**: when
|
|
set, skips the `manager_requirements.txt` reinstall path. Intended for E2E
|
|
environments where those dependencies are provisioned separately.
|
|
- **`TaskHistoryItem.params` field** (Pydantic + `openapi.yaml`): mirrors
|
|
`QueueTaskItem.params` so that task history retains the original request
|
|
payload (nullable when unavailable).
|
|
- **Automated endpoint coverage** — pytest E2E + Playwright specs covering all
|
|
39 unique `(method, path)` endpoints across `glob` and `legacy`. Coverage is
|
|
tracked in `reports/api-coverage-matrix.md` and
|
|
`reports/e2e_test_coverage.md`.
|
|
|
|
### Removed
|
|
|
|
- **Legacy per-operation POST routes consolidated into `POST /v2/manager/queue/batch`**:
|
|
`/v2/manager/queue/{install, uninstall, update, fix, disable, reinstall, abort_current}`.
|
|
The first-party JS client already uses `queue/batch`; only third-party
|
|
scripts that call the per-operation routes directly are affected.
|
|
- **`GET /manager/notice`** (v1, pip-install redirect banner).
|
|
`GET /v2/manager/notice` remains available.
|
|
|
|
### Migration notes
|
|
|
|
- Third-party clients calling `POST /v2/manager/queue/install` (and the other
|
|
per-operation queue routes) must switch to
|
|
`POST /v2/manager/queue/batch` with a body such as
|
|
`{"install": [{id, ver, ...}], "batch_id": "..."}`. See
|
|
`reports/endpoint_scenarios.md` for the full payload shape.
|
|
- Programmatic clients that posted to the CSRF-hardened endpoints with
|
|
`application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`
|
|
must switch to `application/json` (or omit the body entirely when the
|
|
endpoint takes its parameters from the query string).
|
|
- Clients that called any of the methods listed under **Changed → State-changing
|
|
endpoints** with `GET` must switch to `POST`. Query parameters remain valid.
|
|
- Clients that wrote configuration via
|
|
`GET /v2/manager/{db_mode, policy/update, channel_url_list}?value=...`
|
|
must switch to `POST` with JSON body `{"value": "..."}`.
|
|
- Third-party scripts calling
|
|
`POST /v2/comfyui_manager/comfyui_switch_version?ver=...&client_id=...&ui_id=...`
|
|
must switch to `POST` with `Content-Type: application/json` and body
|
|
`{"ver": "...", "client_id": "...", "ui_id": "..."}`. The query-string
|
|
form no longer works.
|
|
- Environments running at `security_level = high` can no longer run
|
|
`do_fix`. Either lower the security level (`normal`, `normal-`, or `weak`
|
|
as appropriate) or skip the fix operation.
|
|
- Environments running at `security_level = high` can no longer mutate
|
|
`db_mode`, `policy/update`, or `channel_url_list` via POST (returns `403`).
|
|
Lower the security level to `normal` or below to change configuration, or
|
|
perform the change from a trusted entry point. Read access via `GET` is
|
|
unaffected.
|
|
|
|
[4.2.1]: https://github.com/Comfy-Org/ComfyUI-Manager/compare/v4.1b6...v4.2.1
|