Escape client_id in OAuth consent details (#3418)

🤖 Generated with GPT-5.2-Codex
This commit is contained in:
Jeremiah Lowin 2026-03-06 17:33:12 -05:00 committed by GitHub
commit 799c4f1673
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 2 deletions

View file

@ -84,7 +84,7 @@ def create_consent_html(
detail_rows = [
("Application Name", html_module.escape(client_name or client_id)),
("Application Website", html_module.escape(client_website_url or "N/A")),
("Application ID", client_id),
("Application ID", html_module.escape(client_id)),
("Redirect URI", redirect_uri_escaped),
(
"Requested Scopes",

View file

@ -7,7 +7,7 @@ from starlette.requests import Request
from starlette.responses import HTMLResponse
from fastmcp.server.auth.oauth_proxy import OAuthProxy
from fastmcp.server.auth.oauth_proxy.ui import create_error_html
from fastmcp.server.auth.oauth_proxy.ui import create_consent_html, create_error_html
from fastmcp.server.auth.providers.jwt import JWTVerifier
@ -99,3 +99,21 @@ class TestErrorPageRendering:
assert b"invalid_scope" in response.body
assert b"doesn't exist" in response.body # HTML-escaped apostrophe
assert b"OAuth Error" in response.body
class TestConsentPageRendering:
"""Test consent page rendering and escaping."""
def test_create_consent_html_escapes_client_id_in_details(self):
"""Test that Application ID is escaped in advanced details."""
html = create_consent_html(
client_id='evil<img src=x onerror=alert("xss")>',
redirect_uri="https://example.com/callback",
scopes=["read"],
txn_id="txn",
csrf_token="csrf",
)
assert 'evil<img src=x onerror=alert("xss")>' not in html
assert "evil&lt;img src=x onerror=alert(&quot;xss&quot;)&gt;" in html