Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/tc39/proposal-symbol-proto
Análise de VulnerabilidadesSegurança WebPapers e PesquisaAprendizado e Educação
GitHubtc39/proposal-symbol-proto

proposal-symbol-proto

Proposta TC39 para mitigar a poluição de protótipos

Ver Repositório
5321há 3 anosRevisado pelo Kitploit

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Mitigação de Poluição de Protótipo / Symbol.proto

Autores: Santiago Díaz (Google)

Champion: Shu-yu Guo (Google)

Estágio: 1

Índice

  • Descrição do Problema
    • Ação fantasmagórica à distância
    • Ataques somente com dados
  • Problemas com freeze, seal e preventExtensions
    • O erro de sobrescrita
    • Granularidade grosseira
    • Pontos de congelamento
    • Tipos de aplicação
  • Solução proposta
    • Fornecer APIs de reflexão
    • Recurso opt-in
      • Refatoração automática
    • O que significa deletar?
  • Bases de código incompatíveis
  • Apêndice
    • E a poluição de construtores?
    • Acesso computado em JS minimizado
    • Exemplos de vulnerabilidades
  • tl;dr

    Esta proposta procura mitigar uma vulnerabilidade em nível de linguagem conhecida como poluição de protótipo (prototype pollution) com um mecanismo que complementa as primitivas de congelamento e um mecanismo para tornar a maioria das bases de código compatíveis com ela. Ela descreve um recurso opt-in que torna os protótipos disponíveis somente por meio de APIs de reflexão. Com isso, a declaração obj[key] não consegue mais acessar protótipos. Bases de código compatíveis com esse recurso são mais intencionais na forma como usam protótipos.

    Descrição do Problema

    Ação fantasmagórica à distância

    Vulnerabilidades de PP permitem que atacantes manipulem objetos que eles não controlam ou aos quais não têm acesso em tempo de execução. Essa primitiva de 'ação fantasmagórica à distância' pode ser usada para alterar a forma de outros objetos e sobrescrever suas propriedades, contaminando assim objetos no runtime.

    Objetos contaminados invalidam as premissas subjacentes de um código que de outra forma seria seguro/correto e podem levar à execução arbitrária de código e a uma ampla gama de outros problemas de segurança em bases de código JS. Bugs de poluição de protótipo se manifestam com frequência em aplicações web, mas também afetam runtimes JS fora da web.

    As propriedades de objetos em JS podem ser gravadas por qualquer código que possa referenciá-las. Em particular, se muitos objetos dependem de uma propriedade compartilhada, qualquer um deles pode efetuar mudanças em todos os outros.

    Ataques somente com dados

    Uma propriedade especial do PP é que ele é um ataque somente com dados, permitindo que a execução de código seja obtida puramente por meio de dados. Por exemplo, veja o seguinte código vulnerável e um exploit correspondente:

    root@kitploit:~
    // source is attacker-controlled
    function merge(target, source) {
      for (let key in source) {
        if (typeof source[key] === 'object')  {
          if(target[key] === undefined) {
            target[key] = {};
          }
          target[key] = merge(target[key], source[key]);
        } else {
          target[key] = source[key];
        }
      }
      return target;
    }
    
    // User input comes as a string
    const userSuppliedObj = JSON.parse('{"__proto__": {"polluted": true}}');
    // Trigger prototype pollution
    merge({}, userSuppliedObj);
    // Create a brand new object
    const newObj = {};
    // Has polluted property
    console.log(newObj.polluted); // true
    

    Observe que o exploit consegue contaminar a criação de novos objetos sem injetar nenhum código estranho.

    Por causa dessa propriedade especial, mitigações modernas contra problemas de execução de código — como a Content Security Policy ou Trusted Types — ficam aquém da proteção contra PP, pois elas se concentram em impor a proveniência do código.

    Nota: ataques somente com dados são relevantes em situações em que o código executado na VM é confiável e a execução arbitrária de código tem impacto de segurança.

    Problemas com freeze, seal e preventExtensions

    As primitivas de congelamento existentes sofrem de problemas de design significativos que tornam improvável sua adoção em larga escala. Elas podem ser úteis para usuários especialistas, mas não são adequadas para serem usadas pela maioria dos desenvolvedores, que razoavelmente esperam que os protótipos sejam mutáveis:

    O erro de sobrescrita

    As APIs de congelamento sofrem do erro de sobrescrita e de outras inconsistências que introduzem bugs em bases de código existentes, fazendo-as lançar erros ou, pior, falhar silenciosamente em modo sloppy. Uma investigação anterior sobre o erro de sobrescrita concluiu que ele é acionado em ~10% das bases de código em modo estrito e 20% em modo sloppy. A investigação foi abandonada logo em seguida.

    Granularidade grosseira

    As APIs de congelamento dão aos desenvolvedores a pesada responsabilidade de saber quais protótipos devem ser congelados para manter uma base de código segura, partindo do princípio de que os desenvolvedores são especialistas em segurança. Essas APIs descrevem o quê, mas não o como da segurança. Congelar Object certamente não é suficiente, pois muitos exploits abusam de Array. E Error, Date, Reflect ou Proxy? Ou futuros tipos nativos? As APIs de congelamento não oferecem respostas para essas perguntas.

    Pontos de congelamento

    As APIs de congelamento assumem um ponto de congelamento estável: um momento fixo em tempo de execução em que os protótipos já se estabilizaram e podem ser congelados. Na prática, esse ponto é volátil e muda ao longo do tempo em bases de código em desenvolvimento ativo. Embora seja possível encontrar esse ponto em muitas aplicações hoje, a adição de novas dependências, polyfills, mudanças na estrutura do código e recursos avançados como hotswapping e ferramentas de desenvolvimento fazem dos pontos de congelamento um alvo móvel.

    Tipos de aplicação

    As APIs de congelamento não conseguem proteger toda a cadeia de protótipos. Em JS, objetos podem ser adicionados ou removidos da cadeia de protótipos a qualquer momento. Para proteger toda a cadeia, é preciso lembrar sempre de congelar os objetos adicionados a ela, um processo propenso a erros. Quando são removidos da cadeia, não é mais possível descongelá-los.

    Solução proposta

    Em resumo: um recurso que expõe os protótipos somente a APIs de reflexão. Se os protótipos não fossem disponibilizados por meio de propriedades como __proto__ ou prototype, não estariam expostos a problemas somente com dados.

    Isso é melhor compreendido por meio de um exemplo: a declaração obj[one][two] = value é vulnerável a PP por meio de obj.__proto__.polluted. Se alguém deletar a propriedade Object.prototype.__proto__, a mesma declaração não é mais vulnerável, pois não consegue usar o único outro caminho para alcançar protótipos, que é obj.constructor.prototype.polluted. Observe que a propriedade prototype não pode ser deletada.

    Esta proposta pode ser implementada fornecendo APIs de reflexão e criando um novo recurso de encapsulamento opt-in que deleta as propriedades dos protótipos. Uma descrição de cada etapa vem a seguir.

    Fornecer APIs de reflexão

    __proto__ é um nome de propriedade legado que pode ser deletado, mas o slot interno por trás dele ainda pode ser lido por meio de Object/Reflect.getPrototypeOf e gravado por meio de Object/Reflect.setPrototypeOf, o que simplesmente continuará tornando essa propriedade acessível a código já em execução.

    Propomos a criação de novas APIs para prototype, por exemplo getClassPrototypeOf e setClassPrototypeOf, que permitiriam que esse nome de propriedade fosse deletado sem mudar de nenhuma forma como essa propriedade especial funciona e dá suporte à VM.

    As APIs de reflexão podem ser polyfilled, o que permite que bases de código endurecidas funcionem em todos os navegadores, inclusive versões mais antigas.

    Recurso opt-in

    Um novo 'recurso de encapsulamento' opt-in em que nenhum nome de propriedade é criado para as funções getter e setter dos slots de protótipos, o que agora é possível porque as referências a essas propriedades podem usar APIs de reflexão em vez disso.

    O recurso é ativado por meio de uma flag fora de banda:

    • Em contextos de navegador, por meio de um cabeçalho HTTP como X-Encapsulate-Prototype: true
    • Em outros contextos, por meio de uma feature flag como --encapsulate-prototype

    Quando o encapsulamento está desativado, os protótipos ficam disponíveis tanto por meio de propriedades quanto por APIs de reflexão.

    Quando o encapsulamento está ativado, os protótipos só ficam disponíveis por meio de APIs de reflexão, tendo deletado tanto __proto__ quanto prototype.

    O encapsulamento também inclui o seguinte recurso de refatoração automática:

    Refatoração automática

    Quando o encapsulamento está ativado, os motores JS que carregam novo código-fonte ativam uma etapa extra em suas fases de parsing que registra todas as notações com ponto para propriedades de protótipo como se fossem chamadas às suas APIs de reflexão. Essa etapa pode ser implementada de forma eficiente e permite que bases de código com dependências de terceiros, transitivas ou carregadas dinamicamente sejam compatíveis com o encapsulamento.

    No futuro, essa mudança abrirá caminho para marcar prototype como descontinuado (deprecated).

    O que significa deletar?

    As propriedades de protótipo poderiam simplesmente ser undefined quando o encapsulamento está ativado, mas poderiam lançar um erro quando houvesse tentativas de leitura/gravação. Isso significaria falhar mais rápido e de forma ruidosa e permitiria testar migrações para as APIs de reflexão/encapsulamento.

    Isso implica tornar os getters e setters de __proto__ e prototype condicionais ao encapsulamento, usando um host hook, da mesma forma que a função eval lança erro sob Content Security Policy.

    Bases de código incompatíveis

    Código que depende de acesso computado a propriedades para referenciar protótipos não é compatível com o encapsulamento nem com a refatoração automática. Ele precisa ser refatorado para referir-se explicitamente a protótipos quando eles são usados. Essa refatoração, na verdade, faz o código expressar intenção, o que torna padrões perigosos visíveis para análise estática. Na prática, bases de código com essa característica costumam ser frameworks de reflexão, ferramentas de depuração e outros casos de uso com uso intensivo de reflexão que provavelmente estão cientes de como usam protótipos.

    Bases de código que usam a palavra prototype para definir propriedades personalizadas não são compatíveis. Essas bases de código podem ser tornadas compatíveis com o encapsulamento se essa propriedade for sempre definida/obtida por meio de notação com colchetes. Historicamente, e com base em consultas ao HTTP Archive, há uma pequena porcentagem de bases de código incompatíveis por esse motivo.

    Apêndice

    E a poluição de construtores?

    Algumas mudanças na propriedade constructor também podem ter ação fantasmagórica à distância. Durante nossa pesquisa, não encontramos vulnerabilidades práticas afetadas por isso.

    O nível de exigência para esse ataque funcionar é significativamente alto: como no PP, é preciso encontrar uma aplicação com gadgets para escrever e ler propriedades arbitrárias. Mas na poluição de construtores, o gadget de leitura deve ler de constructor.polluted em vez de polluted. Isso reduz drasticamente o número de gadgets úteis.

    Acesso computado em JS minimizado

    Alguns JS minimizados podem ser incompatíveis com o modo de encapsulamento, porque o acesso estático a propriedades pode ser minificado em acesso computado. Consultamos o HTTP Archive para obter uma estimativa disso na prática. A tabela a seguir mostra que páginas com esse comportamento ficam consistentemente abaixo de 1% ao longo dos últimos 12 meses para todas as páginas rastreadas com um navegador de desktop:

    TabelaDocumentos que acessam __proto__ ou constructor dinamicamenteTotal de documentos rastreadosProporção
    2023_03_01_desktop5,407,936609,469,4580.89%
    2023_02_01_desktop4,842,383549,089,7080.88%
    2023_01_01_desktop5,283,826589,519,1600.90%
    2022_12_01_desktop5,161,471577,073,8830.89%
    2022_11_01_desktop5,023,169561,726,2390.89%
    2022_10_01_desktop4,393,377476,880,6240.92%
    2022_09_01_desktop4,239,257466,278,7620.91%
    2022_08_01_desktop4,259,814463,784,0470.92%
    2022_07_01_desktop3,011,137339,468,6150.89%
    2022_06_01_desktop2,301,317257,501,2220.89%
    2022_04_01_desktop2,368,577263,144,6570.90%
    2022_03_01_desktop2,319,518259,249,0130.89%

    Exemplos de vulnerabilidades

    A Google tem observado uma tendência de aumento nos bugs submetidos ao nosso Programa de Recompensas por Vulnerabilidades: 1 em 2020, 3 em 2021 e 5 até agora em 2022. Identificamos vários outros em nossa pesquisa interna.

    Exemplos de vulnerabilidades incluem:

    1. Na Web: Vários problemas de XSS em serviços que deveriam estar protegidos por usarem Strict CSP. E uma ampla gama de bibliotecas vulneráveis conhecidas.
    2. No desktop: Um bug em um aplicativo de desktop de propriedade da Google em que os usuários poderiam receber um objeto JSON malicioso que poderia permitir o vazamento de arquivos locais devido a uma vulnerabilidade de poluição. (Atualmente não público, divulgação a definir.)
    3. Em recursos de segurança: Vários bypasses em sanitizadores, incluindo a Chrome's Sanitizer API, DOMPurify e o sanitizador do Closure.
    4. No navegador: Uma fuga de sandbox do Firefox que leva à execução remota de código.
    5. No NodeJS: Vários RCEs foram descobertos.

    Esperamos que o número de aplicações vulneráveis cresça à medida que aplicações JavaScript sejam implantadas em mais ambientes (por exemplo, Electron, Cloudflare Workers etc.). Portanto, uma solução em nível de linguagem é necessária para mitigar ataques em todos os ambientes.

    Baixar ferramenta