🚀 Oferta especial: 60% OFF no CrazyStack - Últimas vagas!Garantir vaga →
Segurança

Prototype Pollution em JavaScript: O erro que compromete cliente e servidor

Descubra como uma vulnerabilidade sutil, mas devastadora, pode afetar qualquer aplicação JavaScript, desde o front-end até o Node.js no backend. Entenda como exploits via prototype pollution podem permitir escalonamento de privilégios, vazamento de dados e redirecionamento para sites maliciosos — e saiba como se proteger.

CrazyStack
15 min de leitura
JavaScriptNode.jsSegurançaPrototype PollutionDeep MergeFront-endBack-end

Por que isso é importante

Uma única linha de código com merge inocente pode abrir toda a sua aplicação JavaScript para ataques, permitindo que invasores inseram propriedades perigosas em todos os objetos do seu sistema. Prototype pollution já derrubou empresas e expôs dados confidenciais — entender este risco muda a forma como você codifica para sempre.

Prototype Pollution: O ataque silencioso no JavaScript

A maior ameaça que poucos veem: quando usamos funções como deep merge para atualizar objetos, podemos sem querer permitir que usuários injetem dados maliciosos, alterando não só um objeto, mas todos os objetos daquela classe. Este ataque, chamado prototype pollution, corrompe a base de dados e a lógica de negócios do seu app.

Como a vulnerabilidade acontece: de frente e de costas

A falha não está só no código do front-end. Toda aplicação Node.js que faz merges ou aceita JSON do usuário também está vulnerável. O ataque explora o fato de __proto__ ser a chave mágica de protótipo em qualquer objeto JavaScript.

O ataque em ação: um exemplo prático

Imagine que você tem um objeto pessoas, indexado por id. Você implementa uma função updatePessoa(id, payload) que faz JSON.parse, depois um deep merge entre os dados enviados e o objeto real. Se alguém envia: {"__proto__": {"admin": true}}, agora todo objeto criado (inclusive futuros!) passa a herdar admin: true.

⚠️Atenção

Prototype pollution não altera só um objeto, mas o protótipo global. Isso significa que cria brechas em todos os lugares do seu sistema — qualquer função, qualquer módulo pode ser afetado.

Impacto prático: privilégios, vazamentos e hijack de endpoints

Com o protótipo poluído, toda checagem do tipo if(obj.admin) pode ser burlada, redirecionamentos podem sair para sites de hackers e endpoints críticos podem ser reconfigurados dos bastidores. O estrago é devastador, especialmente em servidores Node.js, onde um ataque pode afetar todos os usuários conectados — e até persistir por dias sem ser detectado.

Atenção

No servidor, prototype pollution pode comprometer rotas, configurações de banco, permissões de acesso e segredos. Basta um payload JSON vindo do cliente para implodir a confiança.

A origem: o deep merge é culpado?

Geralmente, tudo começa com uma implementação inocente de merge profundo, que adiciona/troca propriedades sem validar nomes críticos como __proto__ ou constructor.prototype. O padrão do JavaScript permite alterar o protótipo dinamicamente, expondo toda a cadeia de objetos.

ℹ️Atenção

Frameworks conhecidos já enfrentaram incidentes causados por esta falha. Nunca confie em merges sem checagem de propriedades perigosas.

Como bloquear o ataque: defesas eficazes

Nunca faça deep merge cego. Sempre filtre as chaves e ignore __proto__, prototype e constructor ao fundir objetos. Se possível, evite completamente deep merge quando não é explicitamente necessário.

Atenção

A solução mais robusta é validar os dados antes do merge, usando libraries consolidadas (como lodash.merge seguro) ou implementando checagem de propriedade explicitamente.

Reavalie o design: você realmente precisa de deep merge?

Muitas vezes, um merge simples de propriedades é suficiente. Se seu objeto não usa níveis aninhados, atualize apenas as chaves esperadas. Quanto menos dinâmica, menos chance de ataque.

Jamais confie no cliente

Códigos escritos para rodar no navegador são território do atacante: tudo pode ser lido, alterado ou forjado facilmente. Toda validação crítica e segurança deve estar replicada e reforçada no backend.

⚠️Atenção

Nunca envie segredos, chaves de API ou qualquer configuração sensível ao cliente. JavaScript não é lugar seguro para informações críticas.

HTTPS é obrigatório: esqueça a "criptografia caseira"

Hoje, com Let's Encrypt gratuito e fácil, todas as trocas entre cliente e servidor devem usar HTTPS. Esqueça tentativas de "criptografia com hash" no front — segurança real começa com TLS.

Check-list final: sua aplicação está protegida?

- Nenhum merge profundo sem filtro
- Validação sempre no back-end
- Nada de segredos no cliente
- Ignore entradas com __proto__/constructor
- HTTPS em todas as rotas
- Use ferramentas testadas e revisadas

Quer saber mais, ver código e hacks inéditos?

Acesse o canal Dev Doido com demonstrações práticas, vulnerabilidades reais e técnicas para blindar seu próximo projeto. Segurança não é opcional: ela começa no detalhe do seu código.

Domine React e Node com o CrazyStack

Aprenda técnicas avançadas de React com nosso curso completo