Poluição de Protótipo do Lado do Cliente
Reading time: 10 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Descobrindo usando Ferramentas Automáticas
As ferramentas https://github.com/dwisiswant0/ppfuzz, https://github.com/kleiton0x00/ppmap e https://github.com/kosmosec/proto-find podem ser usadas para encontrar vulnerabilidades de poluição de protótipo.
Além disso, você também pode usar a extensão do navegador PPScan para escanear automaticamente as páginas que você acessa em busca de vulnerabilidades de poluição de protótipo.
Depurando onde uma propriedade é usada
// Stop debugger where 'potentialGadget' property is accessed
Object.defineProperty(Object.prototype, "potentialGadget", {
__proto__: null,
get() {
console.trace()
return "test"
},
})
Encontrando a causa raiz da Poluição de Protótipos
Uma vez que uma vulnerabilidade de poluição de protótipos tenha sido identificada por qualquer uma das ferramentas, e se o código não for excessivamente complexo, você pode encontrar a vulnerabilidade procurando por palavras-chave como location.hash
, decodeURIComponent
ou location.search
nas Ferramentas de Desenvolvedor do Chrome. Essa abordagem permite que você localize a seção vulnerável do código JavaScript.
Para bases de código maiores e mais complexas, um método simples para descobrir o código vulnerável envolve os seguintes passos:
- Use uma ferramenta para identificar uma vulnerabilidade e obter um payload projetado para definir uma propriedade no construtor. Um exemplo fornecido pelo ppmap pode ser:
constructor[prototype][ppmap]=reserved
. - Defina um ponto de interrupção na primeira linha do código JavaScript que será executado na página. Atualize a página com o payload, pausando a execução neste ponto de interrupção.
- Enquanto a execução do JavaScript estiver pausada, execute o seguinte script no console JS. Este script sinalizará quando a propriedade 'ppmap' for criada, ajudando a localizar sua origem:
function debugAccess(obj, prop, debugGet = true) {
var origValue = obj[prop]
Object.defineProperty(obj, prop, {
get: function () {
if (debugGet) debugger
return origValue
},
set: function (val) {
debugger
origValue = val
},
})
}
debugAccess(Object.prototype, "ppmap")
- Navegue de volta para a aba Sources e selecione “Resume script execution”. O JavaScript continuará executando, e a propriedade 'ppmap' será poluída como esperado. Utilizar o trecho fornecido facilita a identificação do local exato onde a propriedade 'ppmap' é poluída. Ao examinar a Call Stack, diferentes pilhas onde a poluição ocorreu podem ser observadas.
Ao decidir qual pilha investigar, muitas vezes é útil direcionar-se a pilhas associadas a arquivos de bibliotecas JavaScript, pois a poluição de protótipos frequentemente ocorre dentro dessas bibliotecas. Identifique a pilha relevante examinando sua ligação a arquivos de biblioteca (visível no lado direito, semelhante a uma imagem fornecida como orientação). Em cenários com várias pilhas, como aquelas nas linhas 4 e 6, a escolha lógica é a pilha na linha 4, pois representa a ocorrência inicial da poluição e, portanto, a causa raiz da vulnerabilidade. Clicar na pilha o direcionará para o código vulnerável.
Encontrando Gadgets de Script
O gadget é o código que será abusado uma vez que uma vulnerabilidade de PP seja descoberta.
Se a aplicação for simples, podemos procurar por palavras-chave como srcdoc/innerHTML/iframe/createElement
e revisar o código-fonte e verificar se ele leva à execução de javascript. Às vezes, as técnicas mencionadas podem não encontrar gadgets de forma alguma. Nesse caso, a revisão pura do código-fonte revela alguns bons gadgets, como o exemplo abaixo.
Exemplo de Encontrando gadget PP no código da biblioteca Mithil
Verifique este writeup: https://blog.huli.tw/2022/05/02/en/intigriti-revenge-challenge-author-writeup/
Recompilação de payloads para bibliotecas vulneráveis
- https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#prototype-pollution
- https://github.com/BlackFan/client-side-prototype-pollution
Bypass de HTML Sanitizers via PP
Esta pesquisa mostra gadgets de PP para usar para burlar as sanitizações fornecidas por algumas bibliotecas de sanitização de HTML:
- sanitize-html
.png)
- dompurify
.png)
- Closure
<!-- from https://research.securitum.com/prototype-pollution-and-bypassing-client-side-html-sanitizers/ -->
<script>
Object.prototype['* ONERROR'] = 1;
Object.prototype['* SRC'] = 1;
</script>
<script src=https://google.github.io/closure-library/source/closure/goog/base.js></script>
<script>
goog.require('goog.html.sanitizer.HtmlSanitizer');
goog.require('goog.dom');
</script>
<body>
<script>
const html = '<img src onerror=alert(1)>';
const sanitizer = new goog.html.sanitizer.HtmlSanitizer();
const sanitized = sanitizer.sanitize(html);
const node = goog.dom.safeHtmlToNode(sanitized);
document.body.append(node);
</script>
Novas Ferramentas & Automação (2023–2025)
- Burp Suite DOM Invader (v2023.6) – PortSwigger adicionou uma aba dedicada de Prototype-pollution que automaticamente muta nomes de parâmetros (por exemplo,
__proto__
,constructor.prototype
) e detecta propriedades poluídas em pontos de sink dentro da extensão do navegador. Quando um gadget é acionado, o DOM Invader mostra a pilha de execução e a linha exata onde a propriedade foi desreferenciada, tornando a busca manual por breakpoints desnecessária. Combine-o com o snippet "Break on property access" já mostrado acima para rapidamente pivotar de source → sink. - protoStalker – um plug-in de código aberto do Chrome DevTools (lançado em 2024) que visualiza cadeias de protótipos em tempo real e sinaliza gravações em chaves globalmente perigosas, como
onerror
,innerHTML
,srcdoc
,id
, etc. Útil quando você só tem um bundle de produção e não pode instrumentar a etapa de build. - ppfuzz 2.0 (2025) – a ferramenta agora suporta ES-modules, HTTP/2 e endpoints WebSocket. O novo modo
-A browser
inicia uma instância headless do Chromium e enumera automaticamente classes de gadgets forçando APIs do DOM (veja a seção abaixo).
Pesquisa Recente sobre Gadgets de Prototype-Pollution (2022–2025)
Em meados de 2023, pesquisadores da PortSwigger publicaram um artigo mostrando que objetos built-in do navegador podem ser transformados em gadgets XSS confiáveis uma vez poluídos. Como esses objetos estão presentes em todas as páginas, você pode obter execução mesmo que o código da aplicação alvo nunca toque na propriedade poluída.
Exemplo de gadget (funciona em todos os navegadores evergreen ≥ 2023-04):
<script>
// Source (e.g. https://victim/?__proto__[href]=javascript:alert(document.domain))
// For demo we just pollute manually:
Object.prototype.href = 'javascript:alert(`polluted`)' ;
// Sink – URL() constructor implicitly reads `href`
new URL('#'); // breaks into JS; in Chrome you get an alert, Firefox loads "javascript:" URL
</script>
Outros gadgets globais úteis que foram confirmados como funcionais após a poluição (testados em 2024-11):
Classe do Gadget | Propriedade Lida | Primitivo alcançado |
---|---|---|
Notification | title | alert() via clique na notificação |
Worker | name | Execução de JS em Worker dedicado |
Image | src | XSS tradicional onerror |
URLSearchParams | toString | Redirecionamento aberto baseado em DOM |
Veja o artigo da PortSwigger para a lista completa de 11 gadgets e uma discussão sobre escapes de sandbox.
CVEs Notáveis de PP do Lado do Cliente (2023-2025)
- DOMPurify ≤ 3.0.8 – CVE-2024-45801 Um atacante poderia poluir
Node.prototype.after
antes da inicialização do sanitizador, contornando o perfil SAFE_FOR_TEMPLATES e levando a XSS armazenado. O fornecedor corrigiu usando verificaçõesObject.hasOwn()
eObject.create(null)
para mapas internos. - jQuery 3.6.0-3.6.3 – CVE-2023-26136 / CVE-2023-26140
extend()
poderia ser usado em objetos manipulados originados delocation.hash
, introduzindo propriedades arbitrárias emObject.prototype
no contexto de navegação. - sanitize-html < 2.8.1 (2023-10) poluição de protótipo Uma lista de atributos maliciosa como
{"__proto__":{"innerHTML":"<img/src/onerror=alert(1)>"}}
contornou a lista de permissão.
Mesmo que a biblioteca vulnerável viva apenas no cliente, o XSS resultante ainda é explorável remotamente através de parâmetros refletidos, manipuladores de postMessage ou dados armazenados renderizados posteriormente.
Medidas Defensivas Modernas
- Congele o protótipo global cedo (idealmente como o primeiro script):
Object.freeze(Object.prototype);
Object.freeze(Array.prototype);
Object.freeze(Map.prototype);
Esteja ciente de que isso pode quebrar polyfills que dependem de extensões tardias.
2. Use structuredClone()
em vez de JSON.parse(JSON.stringify(obj))
ou trechos de "deepMerge" da comunidade – ele ignora setters/getters e não percorre a cadeia de protótipos.
3. Quando você realmente precisar de funcionalidade de mesclagem profunda, escolha lodash ≥ 4.17.22 ou deepmerge ≥ 5.3.0 que têm saneamento de protótipo embutido.
4. Adicione uma Content-Security-Policy com script-src 'self'
e um nonce estrito. Embora o CSP não impeça todos os gadgets (por exemplo, manipulação de location
), ele bloqueia a maioria dos sinks de innerHTML
.
Referências
-
https://portswigger.net/research/widespread-prototype-pollution-gadgets
-
https://snyk.io/blog/dompurify-prototype-pollution-bypass-cve-2024-45801/
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.