perf_hooks: Histogram.DoImport reads SharedArrayBuffer-backed data without copying (TOCTOU)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 62/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- cpp, javascript
- Área
- security
Línea de trabajo
Read HistogramImpl::DoImport in src/histogram.cc and compare its buffer handling with the SharedArrayBuffer copy in src/node_buffer.cc. Find the existing histogram import tests and check how they cover Uint8Array inputs. Done means SAB-backed input is copied before Histogram::Import parses it, with normal inputs retaining their behavior and tests covering the case.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
HistogramImpl::DoImport in src/histogram.cc accepts a Uint8Array and reads the underlying buffer directly during CBOR parsing. When the Uint8Array is backed by a SharedArrayBuffer, a concurrent Worker thread can mutate the buffer while parsing is in progress, causing a time-of-check/time-of-use (TOCTOU) race.
Affected code
src/histogram.cc — HistogramImpl::DoImport (around line 3202):
Local<Uint8Array> input = args[0].As<Uint8Array>();
auto backing = input->Buffer()->GetBackingStore();
const uint8_t* data =
static_cast<const uint8_t*>(backing->Data()) + input->ByteOffset();
size_t len = input->ByteLength();
// ← no IsSharedArrayBuffer() check
auto histogram = Histogram::Import(data, len); // reads data during multi-step CBOR parse
There is no check for input->Buffer()->IsSharedArrayBuffer(). The CBOR parser in Histogram::Import performs multi-step parsing over data without any snapshot or copy.
Scenario
// Worker A — triggers importHistogram with a SAB-backed view
const sab = new SharedArrayBuffer(exportedBytes.length);
const view = new Uint8Array(sab);
view.set(exportedBytes);
// SAB is shared with Worker B via workerData or postMessage
importHistogram(view); // Worker A starts CBOR parse
// Worker B — running concurrently
const view2 = new Uint8Array(sab); // same SAB
view2[criticalOffset] = 0xff; // mutates header field mid-parse
The perf_hooks worker-import pattern in handleMetricsImportWorker-style code already uses this exact shape: the server creates a SAB, copies request data into it, and passes it to a Worker. If the main thread or another Worker modifies the SAB while the Worker is inside importHistogram, the CBOR parser sees inconsistent data.
Existing precedent
src/node_buffer.cc lines 587–592 already handles this case for Buffer.toString():
if (view->Buffer()->IsSharedArrayBuffer()) {
data_copy = std::make_unique_for_overwrite<char[]>(length);
memcpy(data_copy.get(), data_ptr + start, length);
data_ptr = data_copy.get();
start = 0;
}
Proposed fix
Copy SAB-backed data to a local buffer before passing to Histogram::Import, matching the node_buffer.cc pattern. This eliminates the race without changing behavior for normal (non-SAB) Uint8Array inputs.
Severity
Low. Exploitation requires the caller to intentionally share a SAB with the histogram import thread and mutate it during parsing. This is not remotely triggerable without cooperation from same-process JavaScript. It is a defense-in-depth hardening, not a CVE-eligible vulnerability.
- Lenguaje dominante
- JavaScript
- Estrellas
- 123k
- Forks
- 39.3k
- Merge medio
- 4 d 15 h
- PR fusionados (30 d)
- 238
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de nodejs/node
-
util: parseArgs() treats a `-` inside a short option group as the `--` terminatorPosiblemente ocupada @yohannesjoya la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
http2: content-encoding is incorrectly listed in kSingleValueHeadersPosiblemente ocupada @inoway46 la tomó hace 2 días. Abiertoconfirmed-bug http2
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
nodejs/node#67151 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
util.parseEnv and --env-file keep a leading UTF-8 BOM in the first keyPosiblemente ocupada @helmipradita la tomó hace 4 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
node:internal/inspector/network_http: `TypeError: Missing dataLength` in event when response uses `setEncoding()`Quizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
nodejs/node#66551 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
[Docs] `process.loadEnvFile()` does not document behaviour when variables already existPosiblemente ocupada @Sepandard la tomó hace 38 días. Abiertodoc
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
Los mantenedores suelen responder en 1 día
Todos los issues de nodejs/node
Issues similares
-
Handle HTTP errors when downloading release binariesPosiblemente ocupada @mugenkyou la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
neutralinojs/neutralinojs-cli#468 ·
Los mantenedores suelen responder en 1 día
-
area:ci priority:p0 type:chore
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
lucacasanova/homedeck#2 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
terser/html-minifier-terser#242 ·
-
enhancement good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
MustacheCase/zanadir#516 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
stylelint-scss/stylelint-config-standard-scss#297 · 1 comentario ·