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.