OAuth2 consent page XSS via client application name containing malicious script
ID: security/oauth2-consent-page-xss-via-client-name
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| OAuth2 2.0 | active | — | — | — |
| Spring Security 5.7.10 | active | — | — | — |
| Keycloak 21.0.0 | active | — | — | — |
| Auth0 Node.js SDK 2.42.0 | active | — | — | — |
Root Cause
The OAuth2 authorization server renders the client application name without proper HTML escaping on the consent page, allowing an attacker to register a client with a name containing JavaScript that executes in the user's browser.
generic中文
OAuth2 授权服务器在授权页面上渲染客户端应用名称时未进行正确的 HTML 转义,允许攻击者注册一个包含 JavaScript 的客户端名称,从而在用户浏览器中执行恶意脚本。
Official Documentation
https://datatracker.ietf.org/doc/html/rfc6749#section-3.1Workarounds
-
90% success Apply HTML entity encoding to the client application name before rendering on the consent page. In Java with Spring Security, use `HtmlUtils.htmlEscape(clientName)` in the template. For Keycloak, override the consent form template (consent.ftl) and escape `${client.clientName}` using `<#escape x as x?html>${client.clientName}</#escape>`.
Apply HTML entity encoding to the client application name before rendering on the consent page. In Java with Spring Security, use `HtmlUtils.htmlEscape(clientName)` in the template. For Keycloak, override the consent form template (consent.ftl) and escape `${client.clientName}` using `<#escape x as x?html>${client.clientName}</#escape>`. -
85% success Validate client name during registration to reject any names containing HTML tags or script characters. Use a whitelist approach: allow only alphanumeric characters, spaces, and basic punctuation. Example regex: `^[a-zA-Z0-9\s\-_\.]+$`.
Validate client name during registration to reject any names containing HTML tags or script characters. Use a whitelist approach: allow only alphanumeric characters, spaces, and basic punctuation. Example regex: `^[a-zA-Z0-9\s\-_\.]+$`.
-
80% success Implement output encoding specifically for JavaScript contexts if the client name is used in dynamic attributes. Use a library like OWASP Java Encoder: `Encoder.forJavaScript(clientName)`.
Implement output encoding specifically for JavaScript contexts if the client name is used in dynamic attributes. Use a library like OWASP Java Encoder: `Encoder.forJavaScript(clientName)`.
中文步骤
在授权页面上渲染客户端应用名称之前,应用 HTML 实体编码。在 Java 与 Spring Security 中,在模板中使用 `HtmlUtils.htmlEscape(clientName)`。对于 Keycloak,覆盖授权表单模板 (consent.ftl) 并使用 `<#escape x as x?html>${client.clientName}</#escape>` 转义 `${client.clientName}`。在注册时验证客户端名称,拒绝任何包含 HTML 标签或脚本字符的名称。使用白名单方法:仅允许字母数字字符、空格和基本标点符号。示例正则表达式:`^[a-zA-Z0-9\s\-_\.]+$`。
如果客户端名称用于动态属性,特别针对 JavaScript 上下文实现输出编码。使用 OWASP Java Encoder 等库:`Encoder.forJavaScript(clientName)`。
Dead Ends
Common approaches that don't work:
-
Add Content-Security-Policy header to block inline scripts
40% fail
CSP does not prevent the injection itself; if the client name is rendered in a href attribute or event handler, CSP may not block it, and the script still executes in some contexts.
-
Sanitize client name by removing all HTML tags with a simple regex
35% fail
Attackers can bypass regex-based sanitization with obfuscated payloads (e.g., using Unicode characters or event handlers like onerror).
-
Use a WAF to filter malicious client names during registration
50% fail
WAF rules are often bypassed by encoding the payload (e.g., base64 or URL encoding), and the consent page still renders the name unsafely.