security auth_error ai_generated true

OAuth2 consent page XSS via client application name containing malicious script

ID: security/oauth2-consent-page-xss-via-client-name

Also available as: JSON · Markdown · 中文
88%Fix Rate
85%Confidence
1Evidence
2024-03-15First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
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.1

Workarounds

  1. 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>`.
  2. 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\-_\.]+$`.
  3. 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)`.

中文步骤

  1. 在授权页面上渲染客户端应用名称之前,应用 HTML 实体编码。在 Java 与 Spring Security 中,在模板中使用 `HtmlUtils.htmlEscape(clientName)`。对于 Keycloak,覆盖授权表单模板 (consent.ftl) 并使用 `<#escape x as x?html>${client.clientName}</#escape>` 转义 `${client.clientName}`。
  2. 在注册时验证客户端名称,拒绝任何包含 HTML 标签或脚本字符的名称。使用白名单方法:仅允许字母数字字符、空格和基本标点符号。示例正则表达式:`^[a-zA-Z0-9\s\-_\.]+$`。
  3. 如果客户端名称用于动态属性,特别针对 JavaScript 上下文实现输出编码。使用 OWASP Java Encoder 等库:`Encoder.forJavaScript(clientName)`。

Dead Ends

Common approaches that don't work:

  1. 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.

  2. 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).

  3. 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.