fix(security): harden CSRF with Content-Type gate and expand E2E coverage#2818
Merged
ltdrdata merged 1 commit intomanager-v4from Apr 21, 2026
Merged
fix(security): harden CSRF with Content-Type gate and expand E2E coverage#2818ltdrdata merged 1 commit intomanager-v4from
ltdrdata merged 1 commit intomanager-v4from
Conversation
…rage Defense-in-depth over GET→POST alone: reject the three CORS-safelisted simple-form Content-Types (x-www-form-urlencoded, multipart/form-data, text/plain) on 16 no-body POST handlers (glob + legacy) to block <form method=POST> CSRF that bypasses method-only gating. Move comfyui_switch_version to a JSON body so the preflight requirement applies. Split db_mode/policy/update/channel_url_list into GET(read) + POST(write). Tighten do_fix (high → high+) and gate three previously-ungated config setters at middle. Resynchronize openapi.yaml (27 paths, 30 operations, ComfyUISwitchVersionParams as a shared $ref component). Add E2E harness variants, Playwright config, CSRF/secgate suites, 39-endpoint coverage, and a CHANGELOG. Breaking: legacy per-op POST routes (install/uninstall/fix/disable/update/ reinstall/abort_current) are removed; callers already use queue/batch. Legacy /manager/notice (v1) is removed; /v2/manager/notice is retained. Reported-by: XlabAI Team of Tencent Xuanwu Lab CVSS: 8.1 (AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H)
9694fd7 to
4eb5727
Compare
This was referenced Apr 21, 2026
Merged
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 22, 2026
Align with Comfy-Org/ComfyUI-Manager#2818 (CSRF Content-Type gate). Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params where present. Request shape is compatible with both the current GET backend and the upcoming POST-only backend: body=null + axios default application/json header is explicitly allowed by the backend's reject_simple_form_post gate (only x-www-form-urlencoded, multipart/form-data, text/plain are rejected). Refs: Comfy-Org/ComfyUI-Manager#2818
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 22, 2026
…gate Align with Comfy-Org/ComfyUI-Manager#2818 (shipped in 4.2.0) and Comfy-Org/ComfyUI-Manager#2820 (shipped in 4.2.1). Service layer: - Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params. Request shape compatible with the reject_simple_form_post gate (body=null + axios default application/json header is allowed). UI/state layer (useManagerState): - Add ManagerUIState.INCOMPATIBLE triggered when the Manager backend does not advertise extension.manager.supports_csrf_post. Treated as "not installed" — Manager buttons hide via shouldShowManagerButtons. - One-shot upgrade toast via watch(immediate:true) with a module-level guard; openManager() re-emits the toast on explicit user action. - i18n (en/ko) for the upgrade-required notification. Refs: Comfy-Org/ComfyUI-Manager#2818, Comfy-Org/ComfyUI-Manager#2820
4 tasks
ltdrdata
added a commit
that referenced
this pull request
Apr 22, 2026
This PR merges as the 4.2.1 release, so the [Unreleased] section (PR #2818 CSRF hardening content) becomes part of 4.2.1. Consolidated into a single [4.2.1] entry with Security/Changed/Added/Removed/Migration notes; removed the now-empty [Unreleased] section and its compare link.
ltdrdata
added a commit
that referenced
this pull request
Apr 22, 2026
… feature flag Expose CSRF-POST backend capability as a semantic contract via ComfyUI core's feature_flags mechanism, so frontends (ComfyUI_frontend, extensions) can detect it without parsing version strings. Manager versions prior to 4.2.1 do not set the flag — clients observe its absence and should treat the backend as "incompatible with POST-only state-mutation endpoints" and prompt the user to upgrade. Follow-up to #2818; no endpoint or security behavior change. CHANGELOG: [Unreleased] folded into the 4.2.1 release entry (this PR ships as 4.2.1, so the PR #2818 CSRF hardening content belongs under the same release); compare link anchored at v4.1b6 since no v4.2 tag will be created.
ltdrdata
added a commit
that referenced
this pull request
Apr 22, 2026
… feature flag Lets clients detect CSRF-POST backend support via ComfyUI core's feature_flags instead of parsing version strings. Absence of the flag indicates a Manager version < 4.2.1 that is incompatible with POST-only state-mutation endpoints. Follow-up to #2818; no endpoint or security behavior change. CHANGELOG: fold [Unreleased] into the 4.2.1 entry (this PR ships as 4.2.1); compare link anchored at v4.1b6 (no v4.2 tag planned).
ltdrdata
added a commit
that referenced
this pull request
Apr 22, 2026
… feature flag Lets clients detect CSRF-POST backend support via ComfyUI core's feature_flags instead of parsing version strings. Absence of the flag indicates a Manager version < 4.2.1 that is incompatible with POST-only state-mutation endpoints. Follow-up to #2818; no endpoint or security behavior change.
ltdrdata
added a commit
that referenced
this pull request
Apr 22, 2026
… feature flag (#2823) Lets clients detect CSRF-POST backend support via ComfyUI core's feature_flags instead of parsing version strings. Absence of the flag indicates a Manager version < 4.2.1 that is incompatible with POST-only state-mutation endpoints. Follow-up to #2818; no endpoint or security behavior change.
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 22, 2026
Align with Comfy-Org/ComfyUI-Manager backend changes: - #2818 (4.2.0): CSRF Content-Type gate + GET→POST migration for state-mutation endpoints. - #2823 (4.2.1): register `extension.manager.supports_csrf_post` server feature flag so clients can detect POST-capable backends without version string parsing. Service layer (comfyManagerService): - Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params. Backend's reject_simple_form_post gate allows body=null + axios default application/json header; only the three CORS simple-form types (x-www-form-urlencoded, multipart/form-data, text/plain) are rejected. UI/state layer (useManagerState): - Add ManagerUIState.INCOMPATIBLE — entered when the backend advertises supports_manager_v4 but not supports_csrf_post (old Manager that cannot handle the new POST endpoints). Manager UI is treated as "not installed": shouldShowManagerButtons returns false and consumers (TopMenuSection, MissingNodeCard, MissingPackGroupRow, TabErrors) hide their entry points without any call-site change. - Graceful degraded mode while users remain on Manager <4.2.1: one-shot upgrade toast (warn, 15s) dispatched via watch(immediate:true) with a module-level guard that survives multiple composable instances; openManager() re-emits on explicit user action so stale shortcuts still surface guidance. - i18n (en/ko) for the upgrade-required notification covering Desktop / standalone pip / Manager UI self-update paths. Existing policies preserved: - `--enable-manager` absent → DISABLED (unchanged). - `--enable-manager-legacy-ui` → LEGACY_UI (unchanged). - server feature flags not yet loaded (undefined) → NEW_UI transient fallback (unchanged). Refs: Comfy-Org/ComfyUI-Manager#2818, Comfy-Org/ComfyUI-Manager#2823
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 22, 2026
Align with Comfy-Org/ComfyUI-Manager backend changes: - #2818 (4.2.0): CSRF Content-Type gate + GET→POST migration for state-mutation endpoints. - #2823 (4.2.1): register `extension.manager.supports_csrf_post` server feature flag so clients can detect POST-capable backends without version string parsing. Service layer (comfyManagerService): - Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params. Backend's reject_simple_form_post gate allows body=null + axios default application/json header; only the three CORS simple-form types (x-www-form-urlencoded, multipart/form-data, text/plain) are rejected. UI/state layer (useManagerState): - Add ManagerUIState.INCOMPATIBLE — entered when the backend advertises supports_manager_v4 but not supports_csrf_post (old Manager that cannot handle the new POST endpoints). Manager UI is treated as "not installed": shouldShowManagerButtons returns false and consumers (TopMenuSection, MissingNodeCard, MissingPackGroupRow, TabErrors) hide their entry points without any call-site change. - Graceful degraded mode while users remain on Manager <4.2.1: one-shot upgrade toast (warn, 15s) dispatched via watch(immediate:true) with a module-level guard that survives multiple composable instances; openManager() re-emits on explicit user action so stale shortcuts still surface guidance. - i18n (en/ko) for the upgrade-required notification covering Desktop / standalone pip / Manager UI self-update paths. Existing policies preserved: - `--enable-manager` absent → DISABLED (unchanged). - `--enable-manager-legacy-ui` → LEGACY_UI (unchanged). - server feature flags not yet loaded (undefined) → NEW_UI transient fallback (unchanged). Refs: Comfy-Org/ComfyUI-Manager#2818, Comfy-Org/ComfyUI-Manager#2823
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 23, 2026
Align with Comfy-Org/ComfyUI-Manager backend changes: - #2818 (4.2.0): CSRF Content-Type gate + GET→POST migration for state-mutation endpoints. - #2823 (4.2.1): register `extension.manager.supports_csrf_post` server feature flag so clients can detect POST-capable backends without version string parsing. Service layer (comfyManagerService): - Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params. Backend's reject_simple_form_post gate allows body=null + axios default application/json header; only the three CORS simple-form types (x-www-form-urlencoded, multipart/form-data, text/plain) are rejected. UI/state layer (useManagerState): - Add ManagerUIState.INCOMPATIBLE — entered when the backend advertises supports_manager_v4 but not supports_csrf_post (old Manager that cannot handle the new POST endpoints). Manager UI is treated as "not installed": shouldShowManagerButtons returns false and consumers (TopMenuSection, MissingNodeCard, MissingPackGroupRow, TabErrors) hide their entry points without any call-site change. - Graceful degraded mode while users remain on Manager <4.2.1: one-shot upgrade toast (warn, 15s) dispatched via watch(immediate:true) with a module-level guard that survives multiple composable instances; openManager() re-emits on explicit user action so stale shortcuts still surface guidance. - i18n (en/ko) for the upgrade-required notification covering Desktop / standalone pip / Manager UI self-update paths. Existing policies preserved: - `--enable-manager` absent → DISABLED (unchanged). - `--enable-manager-legacy-ui` → LEGACY_UI (unchanged). - server feature flags not yet loaded (undefined) → NEW_UI transient fallback (unchanged). Refs: Comfy-Org/ComfyUI-Manager#2818, Comfy-Org/ComfyUI-Manager#2823
ltdrdata
added a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 23, 2026
Align with Comfy-Org/ComfyUI-Manager backend changes: - #2818 (4.2.0): CSRF Content-Type gate + GET→POST migration for state-mutation endpoints. - #2823 (4.2.1): register `extension.manager.supports_csrf_post` server feature flag so clients can detect POST-capable backends without version string parsing. Service layer (comfyManagerService): - Convert START_QUEUE, UPDATE_ALL, UPDATE_COMFYUI, REBOOT to POST with body=null and preserved query params. Backend's reject_simple_form_post gate allows body=null + axios default application/json header; only the three CORS simple-form types (x-www-form-urlencoded, multipart/form-data, text/plain) are rejected. UI/state layer (useManagerState): - Add ManagerUIState.INCOMPATIBLE — entered when the backend advertises supports_manager_v4 but not supports_csrf_post (old Manager that cannot handle the new POST endpoints). Manager UI is treated as "not installed": shouldShowManagerButtons returns false and consumers (TopMenuSection, MissingNodeCard, MissingPackGroupRow, TabErrors) hide their entry points without any call-site change. - Graceful degraded mode while users remain on Manager <4.2.1: one-shot upgrade toast (warn, 15s) dispatched via watch(immediate:true) with a module-level guard that survives multiple composable instances; openManager() re-emits on explicit user action so stale shortcuts still surface guidance. - i18n (en/ko) for the upgrade-required notification covering Desktop / standalone pip / Manager UI self-update paths. Existing policies preserved: - `--enable-manager` absent → DISABLED (unchanged). - `--enable-manager-legacy-ui` → LEGACY_UI (unchanged). - server feature flags not yet loaded (undefined) → NEW_UI transient fallback (unchanged). Refs: Comfy-Org/ComfyUI-Manager#2818, Comfy-Org/ComfyUI-Manager#2823
christian-byrne
pushed a commit
to Comfy-Org/ComfyUI_frontend
that referenced
this pull request
Apr 23, 2026
## Summary Align `comfyManagerService` and Manager UI state with CSRF hardening in [Comfy-Org/ComfyUI-Manager#2818](Comfy-Org/ComfyUI-Manager#2818) (4.2.0, Content-Type gate + GET→POST migration) and [Comfy-Org/ComfyUI-Manager#2823](Comfy-Org/ComfyUI-Manager#2823) (4.2.1, `extension.manager.supports_csrf_post` feature flag). ## Changes - **Service layer**: Convert 4 state-mutation endpoints (`START_QUEUE`, `UPDATE_ALL`, `UPDATE_COMFYUI`, `REBOOT`) from GET to POST. `body=null` + axios default `Content-Type: application/json` is allowed by the backend's `reject_simple_form_post` gate (only the three CORS simple-form types are rejected). - **UI/state layer**: Add `ManagerUIState.INCOMPATIBLE` triggered when the backend advertises `supports_manager_v4` but not `supports_csrf_post`. Manager UI is treated as "not installed" — buttons hide via `shouldShowManagerButtons` with zero call-site changes across `TopMenuSection`, `MissingNodeCard`, `MissingPackGroupRow`, `TabErrors`. - **Graceful degraded mode**: One-shot upgrade toast (warn, 15s) dispatched via `watch(immediate:true)` with a module-level guard that survives multiple composable instances. `openManager()` re-emits on explicit user action so stale shortcuts still surface guidance. i18n (en/ko) covering Desktop / standalone pip / Manager UI self-update paths. - **Breaking**: None. Existing policies preserved (`--enable-manager` absent → `DISABLED`; `--enable-manager-legacy-ui` → `LEGACY_UI`; feature flags not yet loaded → `NEW_UI` transient fallback). ## Review Focus - Decision-tree ordering in `useManagerState.ts`: `supports_csrf_post` check evaluates before `NEW_UI`/`LEGACY_UI` branches so stale Manager backends never reach the enabled paths. - Toast guard: module-level `incompatibleToastShown` survives multiple composable instances (tests verify 3× `useManagerState()` = 1 toast call). - `generatedManagerTypes.ts` still declares the 4 endpoints as GET; regeneration follows once Manager 4.2.1 OpenAPI is published. Runtime is unaffected since axios operates on the route string. ## References - [Comfy-Org/ComfyUI-Manager#2818](Comfy-Org/ComfyUI-Manager#2818) — CSRF Content-Type gate + GET→POST migration (4.2.0) - [Comfy-Org/ComfyUI-Manager#2823](Comfy-Org/ComfyUI-Manager#2823) — `supports_csrf_post` feature flag (4.2.1) - [comfyui-manager 4.2.1 on PyPI](https://pypi.org/project/comfyui-manager/4.2.1) — release package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
<form method=POST>that bypasses method-only gating. The three CORS-safelisted simple-form Content-Types (x-www-form-urlencoded,multipart/form-data,text/plain) are rejected with 400; any other Content-Type forces a CORS preflight the server does not answer.comfyui_switch_versionmigrated to JSON body ({ver, client_id, ui_id}).db_mode/policy/update/channel_url_listsplit into GET(read) + POST(write, JSON body).do_fix'high'→'high+'(align withSECURITY_MESSAGE_HIGH_P);comfyui_switch_versionnewly gated at'high+'; three previously-ungated config setters (db_mode,policy/update,channel_url_list) now gated at'middle'.openapi.yamlfully resynchronized (27 paths, 30 operations, 3 dual-method splits).ComfyUISwitchVersionParamsconsolidated as a shared$refcomponent.start_comfyui_{legacy,permissive,strict}.sh), Playwright config + 6 legacy-UI spec files, pytest CSRF/secgate suites, 39-endpoint coverage matrix.CHANGELOG.md(Keep a Changelog 1.1.0) added.Breaking changes (migration notes in
CHANGELOG.md)POST /v2/manager/queue/batch:queue/install,queue/uninstall,queue/fix,queue/disable,queue/update,queue/reinstall,queue/abort_current.GET /manager/notice(v1) removed;/v2/manager/noticeretained.Related
mainbranch (v1/manager/*routes) handling the same CVE: fix(security): harden CSRF with Content-Type gate and OpenAPI sync #2819fix(security): harden CSRF with Content-Type gate and ...) and identicalReported-by/CVSStrailer for audit cross-reference (git log --grep='XlabAI' --all).Test plan
ruff check comfyui_manager/→ All checks passedpython -m py_compileon all touched files → OKpytest tests/ --ignore=tests/e2e --ignore=tests/playwright→ 206 passed, 12 skipped (baseline preserved)pytest --collect-only tests/e2e/test_e2e_csrf.py tests/e2e/test_e2e_csrf_legacy.py→ 110 testspython scripts/verify_audit_counts.py→ PASS (122,0,0,1,123)Review summary
References