fix(security): escape reflected input in SSO, roots, SIEM, LLM chat responses (CWE-79) - #5869
Open
jonpspri wants to merge 4 commits into
Open
fix(security): escape reflected input in SSO, roots, SIEM, LLM chat responses (CWE-79)#5869jonpspri wants to merge 4 commits into
jonpspri wants to merge 4 commits into
Conversation
…WE-79)
The provider_id path parameter was reflected unescaped in the 404 detail and success message of DELETE /sso/providers/{provider_id}. Escape it with html.escape and add regression tests exercising attacker-controlled input.
Signed-off-by: Jonathan Springer <jps@s390x.com>
… output (CWE-79) The uri path parameter was reflected unescaped in the remove_root debug log, 404 detail (via the RootServiceNotFoundError message, which embeds the URI), error log, and success message. Escape all reflections with html.escape and add regression tests exercising attacker-controlled input. Signed-off-by: Jonathan Springer <jps@s390x.com>
destination_name and ValueError/KeyError details (which can embed attacker-controlled names) were reflected unescaped in SIEM admin API 400/404 responses and test_destination results. Escape with html.escape at the router and service layers and add regression tests exercising attacker-controlled input. Signed-off-by: Jonathan Springer <jps@s390x.com>
user_id was reflected unsanitized in connect, chat, disconnect, and status responses, and exception text in the disconnect warning field. Apply SecurityValidator.sanitize_display_text to all reflected outputs and add regression tests exercising attacker-controlled input. Signed-off-by: Jonathan Springer <jps@s390x.com>
jonpspri
requested review from
Lang-Akshay,
brian-hussey,
crivetimihai,
ja8zyjits and
msureshkumar88
as code owners
July 25, 2026 08:59
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.
Closes #5856
Summary
Reflected cross-site scripting (CWE-79) fixes: user-controlled input was returned unescaped in several API responses. This PR escapes or sanitizes every reflection site:
DELETE /sso/providers/{provider_id}):provider_idescaped withhtml.escapein the 404 detail and success message.DELETE /roots/{uri}):uriescaped in the debug log, error log, success message, and the 404 detail (theRootServiceNotFoundErrormessage embeds the URI).destination_nameescaped before reaching the service layer;ValueError/KeyErrordetails (which can embed attacker-controlled names) escaped in 400/404 responses.destination_nameescaped intest_destinationresults (ok and failure paths).user_idpassed throughSecurityValidator.sanitize_display_textin connect, chat, disconnect, and status responses; disconnect warning text sanitized as well.Changes
mcpgateway/routers/sso.py—html.escape(provider_id)in delete endpoint detail/message.mcpgateway/main.py—html.escapeon allurireflections inremove_root.mcpgateway/routers/siem.py—html.escapeon destination name and error details.mcpgateway/services/siem_export_service.py—html.escape(destination_name)in test results.mcpgateway/routers/llmchat_router.py—SecurityValidator.sanitize_display_texton reflecteduser_id/warning outputs.<script>alert(1)</script>), asserting the raw payload is absent and the escaped form is present. Each test fails on unmodifiedmainand passes with the fix (verified by temporarily reverting one escape and watching its test fail).Verification
pytest tests/unit/mcpgateway/routers/test_sso_router.py tests/unit/mcpgateway/test_main.py tests/unit/mcpgateway/routers/test_siem.py tests/unit/mcpgateway/services/test_siem_export_service.py tests/unit/mcpgateway/routers/test_llmchat_router.py— 546 passed.make ruff bandit interrogate pylint verify— all green.