|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to **ComfyUI-Manager** are documented in this file. |
| 4 | + |
| 5 | +The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), |
| 6 | +and this project adheres to [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). |
| 7 | + |
| 8 | +## [Unreleased] |
| 9 | + |
| 10 | +Security-hardening release on branch `fix/csrf-post-conversion`. Contains |
| 11 | +breaking-ish API changes for state-mutating endpoints. See **Migration notes** |
| 12 | +below before upgrading programmatic clients. |
| 13 | + |
| 14 | +### Security |
| 15 | + |
| 16 | +- **CSRF Content-Type gate**: 18 state-mutation POST handlers (9 in `glob`, 9 in |
| 17 | + `legacy`) now reject the three CORS "simple request" Content-Types |
| 18 | + (`application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`). |
| 19 | + This closes the residual `<form method="POST">` bypass route that remained |
| 20 | + after the GET→POST transition. Legitimate clients using `application/json` |
| 21 | + (or no body) are unaffected. |
| 22 | +- **`do_fix` security level raised from `high` to `high+`**: aligns the |
| 23 | + enforcement gate (`is_allowed_security_level`) with the log text emitted by |
| 24 | + `SECURITY_MESSAGE_HIGH_P`. Both `glob/manager_server.py` and |
| 25 | + `legacy/manager_server.py` updated in lockstep. Environments running at |
| 26 | + `security_level = high` can no longer fix a nodepack — use |
| 27 | + `security_level = normal` or lower. |
| 28 | +- **Config setters now gated at `middle` security level**: |
| 29 | + `POST /v2/manager/db_mode`, `POST /v2/manager/policy/update`, and |
| 30 | + `POST /v2/manager/channel_url_list` now check |
| 31 | + `is_allowed_security_level('middle')` before mutating configuration (both |
| 32 | + `glob` and `legacy`). Closes a pre-existing gap where the write path was |
| 33 | + reachable at any security level. Reads (`GET`) remain unrestricted. |
| 34 | + |
| 35 | +### Changed |
| 36 | + |
| 37 | +- **State-changing endpoints converted from `GET` to `POST`** (CSRF hardening): |
| 38 | + `/v2/manager/queue/{update_all, reset, start, update_comfyui}`, |
| 39 | + `/v2/snapshot/{remove, restore, save}`, |
| 40 | + `/v2/comfyui_manager/comfyui_switch_version`, |
| 41 | + `/v2/manager/reboot`. |
| 42 | + Query-string parameters are preserved where they existed; only the HTTP |
| 43 | + method changes. |
| 44 | +- **`POST /v2/comfyui_manager/comfyui_switch_version` parameters moved from |
| 45 | + query string to JSON body** (REST idiom + body-reading CSRF posture): |
| 46 | + The handler now consumes `application/json` with the body shape |
| 47 | + `{"ver": "...", "client_id": "...", "ui_id": "..."}` instead of reading |
| 48 | + `?ver=...&client_id=...&ui_id=...` from the URL. Because body-reading |
| 49 | + handlers are already covered by the CORS-preflight mechanism for |
| 50 | + cross-origin protection, the Content-Type rejection gate introduced for |
| 51 | + the other state-mutation endpoints is intentionally NOT applied here |
| 52 | + (see `comfyui_manager/common/manager_security.py` module docstring). |
| 53 | + The first-party JS client in `comfyui_manager/js/comfyui-manager.js` |
| 54 | + was updated in the same change; third-party callers must migrate. |
| 55 | +- **Config endpoints split into `GET` (read) + `POST` (write)**: |
| 56 | + `/v2/manager/{db_mode, policy/update, channel_url_list}`. `GET` returns the |
| 57 | + current value; `POST` accepts a JSON body `{"value": "..."}`. The prior |
| 58 | + single-method form that accepted a `?value=...` query parameter on either |
| 59 | + verb is retired. |
| 60 | +- **`openapi.yaml` fully resynchronized** with the server: HTTP methods, the |
| 61 | + dual-method splits above, request-body schemas for the new POST setters, |
| 62 | + and the `TaskHistoryItem.params` field now match `manager_server.py`. |
| 63 | +- **Legacy `restart(self)` → `restart(request)`**: parameter name corrected. |
| 64 | + No behavioral change. |
| 65 | + |
| 66 | +### Added |
| 67 | + |
| 68 | +- **E2E test harness variants** for security-level and legacy-mode scenarios: |
| 69 | + `tests/e2e/scripts/start_comfyui_legacy.sh`, |
| 70 | + `tests/e2e/scripts/start_comfyui_permissive.sh`, |
| 71 | + `tests/e2e/scripts/start_comfyui_strict.sh`. See |
| 72 | + `docs/guide/GUIDE_E2E_TEST.md` for usage. |
| 73 | +- **`COMFYUI_MANAGER_SKIP_MANAGER_REQUIREMENTS` environment variable**: when |
| 74 | + set, skips the `manager_requirements.txt` reinstall path. Intended for E2E |
| 75 | + environments where those dependencies are provisioned separately. |
| 76 | +- **`TaskHistoryItem.params` field** (Pydantic + `openapi.yaml`): mirrors |
| 77 | + `QueueTaskItem.params` so that task history retains the original request |
| 78 | + payload (nullable when unavailable). |
| 79 | +- **Automated endpoint coverage** — pytest E2E + Playwright specs covering all |
| 80 | + 39 unique `(method, path)` endpoints across `glob` and `legacy`. Coverage is |
| 81 | + tracked in `reports/api-coverage-matrix.md` and |
| 82 | + `reports/e2e_test_coverage.md`. |
| 83 | + |
| 84 | +### Removed |
| 85 | + |
| 86 | +- **Legacy per-operation POST routes consolidated into `POST /v2/manager/queue/batch`**: |
| 87 | + `/v2/manager/queue/{install, uninstall, update, fix, disable, reinstall, abort_current}`. |
| 88 | + The first-party JS client already uses `queue/batch`; only third-party |
| 89 | + scripts that call the per-operation routes directly are affected. |
| 90 | +- **`GET /manager/notice`** (v1, pip-install redirect banner). |
| 91 | + `GET /v2/manager/notice` remains available. |
| 92 | + |
| 93 | +### Migration notes |
| 94 | + |
| 95 | +- Third-party clients calling `POST /v2/manager/queue/install` (and the other |
| 96 | + per-operation queue routes) must switch to |
| 97 | + `POST /v2/manager/queue/batch` with a body such as |
| 98 | + `{"install": [{id, ver, ...}], "batch_id": "..."}`. See |
| 99 | + `reports/endpoint_scenarios.md` for the full payload shape. |
| 100 | +- Programmatic clients that posted to the CSRF-hardened endpoints with |
| 101 | + `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain` |
| 102 | + must switch to `application/json` (or omit the body entirely when the |
| 103 | + endpoint takes its parameters from the query string). |
| 104 | +- Clients that called any of the methods listed under **Changed → State-changing |
| 105 | + endpoints** with `GET` must switch to `POST`. Query parameters remain valid. |
| 106 | +- Clients that wrote configuration via |
| 107 | + `GET /v2/manager/{db_mode, policy/update, channel_url_list}?value=...` |
| 108 | + must switch to `POST` with JSON body `{"value": "..."}`. |
| 109 | +- Third-party scripts calling |
| 110 | + `POST /v2/comfyui_manager/comfyui_switch_version?ver=...&client_id=...&ui_id=...` |
| 111 | + must switch to `POST` with `Content-Type: application/json` and body |
| 112 | + `{"ver": "...", "client_id": "...", "ui_id": "..."}`. The query-string |
| 113 | + form no longer works. |
| 114 | +- Environments running at `security_level = high` can no longer run |
| 115 | + `do_fix`. Either lower the security level (`normal`, `normal-`, or `weak` |
| 116 | + as appropriate) or skip the fix operation. |
| 117 | +- Environments running at `security_level = high` can no longer mutate |
| 118 | + `db_mode`, `policy/update`, or `channel_url_list` via POST (returns `403`). |
| 119 | + Lower the security level to `normal` or below to change configuration, or |
| 120 | + perform the change from a trusted entry point. Read access via `GET` is |
| 121 | + unaffected. |
| 122 | + |
| 123 | +[Unreleased]: https://github.com/Comfy-Org/ComfyUI-Manager/compare/v4.1b6...HEAD |
0 commit comments