This commit is contained in:
Sai Asish Y 2026-05-11 20:01:17 +00:00 committed by GitHub
commit d6af85be35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 5 deletions

View File

@ -333,7 +333,7 @@ def _reject_simple_form_content_type(request):
Applied ONLY to POST handlers that do not consume a request body (e.g.,
/snapshot/save, /manager/queue/{reset,start,update_comfyui},
/manager/reboot). These are vulnerable to cross-origin <form method=POST>
attacks because the handler accepts the request without parsing any body
attacks because the handler accepts the request without parsing any body,
the attacker needs no ability to forge a valid payload, only to point a
hidden form at the URL.
@ -342,8 +342,8 @@ def _reject_simple_form_content_type(request):
body because the browser refuses to send ``application/json`` without a
CORS preflight, which this server does not answer.
DO NOT add this gate to body-reading handlers redundant and UX-breaking.
DO NOT remove this gate from no-body handlers this is the bypass vector.
DO NOT add this gate to body-reading handlers, redundant and UX-breaking.
DO NOT remove this gate from no-body handlers, this is the bypass vector.
aiohttp's ``request.content_type`` normalizes the header (lower-cases,
strips parameters), so ``multipart/form-data; boundary=----X`` is compared
@ -353,8 +353,12 @@ def _reject_simple_form_content_type(request):
web.Response(status=400) when the request has a simple-form
Content-Type that must be rejected. None when the request is allowed
to proceed (no Content-Type, application/json, or any non-simple
Content-Type).
Content-Type, or no request object, internal caller).
"""
# Internal callers (e.g. legacy-UI batch flows) invoke route handlers
# directly with request=None; there is no Content-Type to gate.
if request is None:
return None
if request.content_type in _SIMPLE_FORM_CONTENT_TYPES:
return web.Response(
status=400,

View File

@ -23,7 +23,7 @@ from aiohttp.test_utils import TestClient, TestServer
# Parse the helper from manager_server.py without importing it, to avoid
# pulling in the full ComfyUI/PromptServer stack. Note: we intentionally do
# NOT add the `glob/` directory to sys.path the dir name would shadow
# NOT add the `glob/` directory to sys.path, the dir name would shadow
# Python's stdlib `glob` module and break pytest collection.
REPO_ROOT = Path(__file__).resolve().parent.parent
@ -116,6 +116,12 @@ class ContentTypeRejectionTest(unittest.TestCase):
r = self._post({"Content-Type": "application/json"})
self.assertEqual(r.status, 200)
def test_none_request_allowed(self):
# Internal callers (e.g. legacy-UI batch flows) invoke route handlers
# directly with request=None; helper must not raise AttributeError.
# Regression test for issue #2843.
self.assertIsNone(_reject_simple_form_content_type(None))
if __name__ == "__main__":
unittest.main(verbosity=2)