Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PT-BR] v8-memory-corruption-stack-overflow #2714

Merged
merged 7 commits into from
Oct 30, 2019
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: Corrupção de Memória no V8 e Stack Overflow (consertado no Node v0.8.28 e v0.10.30)
date: 2014-07-31T19:00:00.000Z
slug: v8-memory-corruption-stack-overflow
category: vulnerability
layout: blog-post.hbs
---

Uma vulnerabilidade de corrupção de memória, que resulta em um 'denial-of-service',
foi identificado nas versões do V8 que acompanhavam o Node.js 0.8 e 0.10. Em
certas circunstancias, um workload com uma recursividade profunda poderia ocasionar
um GC e receber um interrupção que talvez transborde a pilha e resulte em um erro
de segmentação. Por exemplo, se o seu workload involve sucessivas chamadas ao
`JSON.parse` e os objects a serem parseados forem significativamente profundos, você
pode se deparar com o processo sendo abortado enquanto está sendo feito o parse.

Esse problema foi identificado por Tom Steele do [^Lift
Security](https://liftsecurity.io/) e Fedor Indunty, Membro do Time Core do Node.js
trabalhou junto com o time do V8 para descobrir a resolução.

A issue do V8 está descrita aqui https://codereview.chromium.org/339883002

Ela chegou no repositório do Node aqui:
https://github.com/joyent/node/commit/530af9cb8e700e7596b3ec812bad123c9fa06356

E foi lançada nas seguintes versões:

* [v0.10.30](https://nodejs.org/dist/v0.10.30)
* [v0.8.28](https://nodejs.org/dist/v0.8.28)

### A Correção

O backport da correção para o Node.js é

```diff
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h
index b90191d..2769ca7 100644
--- a/deps/v8/src/isolate.h
+++ b/deps/v8/src/isolate.h
@@ -1392,14 +1392,9 @@ class StackLimitCheck BASE_EMBEDDED {
public:
explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }

- bool HasOverflowed() const {
+ inline bool HasOverflowed() const {
StackGuard* stack_guard = isolate_->stack_guard();
- // Stack has overflowed in C++ code only if stack pointer exceeds the C++
- // stack guard and the limits are not set to interrupt values.
- // TODO(214): Stack overflows are ignored if a interrupt is pending. This
- // code should probably always use the initial C++ limit.
- return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) &&
- stack_guard->IsStackOverflow();
+ return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit();
}
private:
Isolate* isolate_;
```

### Remediação

O melhor curso de ação é corrigir ou atualizar o Node.js

### Mitigação

Para mitigar contra parseamento de JSON profundo, você pode limitar o tamanho da string,
ou banir clientes que dispararem um `RangeError` no parseamento do JSON.

Não existe tamanho máximo especifico para uma string JSON, contudo mantendo o máximo
do tamanho de uma corpo de messagem conhecida é sugerido. Se o corpo de suas mensagens
não pode ser maior que 20k, não tem razão para aceitar corpos de 1MB.

Para frameworks web que fazem o parse de JSON automático, talvez você precisa configurar
as rotas para aceitar payload de JSON com um tamanho máximo no corpo.

* [expressjs](http://expressjs.com) e [krakenjs](http://krakenjs.com) usados com o plugin [body-parser](https://github.com/expressjs/body-parser#bodyparserjsonoptions) aceita um parâmetro `limit` na sua configuração JSON
* [Hapi.js](http://hapijs.com) tem `payload.maxBytes` https://github.com/spumko/hapi/blob/master/docs/Reference.md
* [restify](http://mcavage.me/node-restify/#Bundled-Plugins) é empacotado com `bodyParser` que aceita `maxBodySize`