CVE Patch Review

GHSA-42H9-826W-CGV3: Root-Cause Fix for Axios formDataToJSON Recursion DoS

GHSA-42H9-826W-CGV3 · Updated 2026-07-20 Root-cause

Summary

Axios addressed the reported denial-of-service condition in formDataToJSON by adding an explicit nesting-depth guard before recursive path construction. The patch throws AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED once parsed form key depth exceeds 100, preventing stack exhaustion from attacker-controlled deeply nested field names. The same change set also includes broader hardening for prototype-pollution-safe config reads and related request-path validation, but the recursion issue itself appears directly and specifically fixed at the parser entry point.

Analysis

Vulnerability

GHSA-42H9-826W-CGV3 describes a denial-of-service condition in Axios where formDataToJSON recursively materializes object paths from attacker-controlled form field names. In the vulnerable flow, the parser called buildPath(parsePropPath(name), value, obj, 0) without bounding nesting depth, so a single request containing a deeply nested key such as repeated [x] segments could drive unbounded recursion and crash a Node.js process via stack exhaustion. The advisory summary and the patch diff in pull request #11001 and commit 1417285c69344bbcc6420a021f67dee0c6fedb2d align on this root cause.

// vulnerable behavior in lib/helpers/formDataToJSON.js
buildPath(parsePropPath(name), value, obj, 0);

The exploitability is straightforward because the recursion depth is derived from input structure rather than authenticated state or server-side resource ownership. Any application path that accepts multipart or form-like input and invokes this helper can be forced into pathological recursion.

Patch

The fix in #11001 adds an explicit depth limit in lib/helpers/formDataToJSON.js. The parser now imports AxiosError, defines MAX_FORM_DATA_TO_JSON_DEPTH = 100, computes depth from the parsed property path, and rejects over-deep inputs before entering recursive object construction. The associated unit test in commit 1417285c69344bbcc6420a021f67dee0c6fedb2d verifies that a field name with 101 nested segments throws ERR_FORM_DATA_DEPTH_EXCEEDED instead of overflowing the stack.

var AxiosError = require('../core/AxiosError');

var MAX_FORM_DATA_TO_JSON_DEPTH = 100;

function assertPathDepth(path) {
  var depth = path.length - 1;

  if (depth > MAX_FORM_DATA_TO_JSON_DEPTH) {
    throw new AxiosError(
      'Maximum object depth of ' + MAX_FORM_DATA_TO_JSON_DEPTH + ' exceeded (got ' + depth + ' levels)',
      AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED
    );
  }
}

var path = parsePropPath(name);
assertPathDepth(path);
buildPath(path, value, obj, 0);

The same patch train also adds a depth assertion in toFormData, plus multiple prototype-pollution-safe property reads in adapters and URL-building helpers. Those changes are security hardening, but they are orthogonal to the recursion DoS itself. Relevant source references are pull request #11001, commit 1417285c69344bbcc6420a021f67dee0c6fedb2d, and the advisory at GitHub Security Advisory.

Review

Pros

  • The mitigation is placed at the correct choke point: immediately after parsePropPath(name) and before recursive descent. That directly addresses the uncontrolled recursion primitive rather than relying on downstream behavior.
  • The failure mode is explicit and typed. Throwing AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED gives callers a deterministic signal instead of a generic runtime stack overflow.
  • The test coverage is relevant and exploit-shaped. The new unit test constructs a nested field name generator and asserts rejection at depth 101, demonstrating prevention before stack exhaustion.
  • The patch also mirrors the same depth-control concept in toFormData, reducing asymmetry between serialization and deserialization paths.

Cons

  • The chosen limit of 100 is a policy decision with no rationale in the provided sources. It is likely safe, but compatibility impact for legitimate deeply nested payloads is not discussed.
  • The guard only constrains path depth, not total field count or aggregate object expansion cost. Extremely broad but shallow inputs may still be expensive, though that is a different resource-consumption class than the reported recursion crash.
  • The patch bundle mixes several unrelated hardening changes. While beneficial overall, that increases review surface and can obscure the minimal fix for this advisory.

Verdict

Root-cause.

This patch fixes the reported issue at its source by bounding attacker-controlled nesting before buildPath recurses. The vulnerable behavior was not merely an unsafe exception path or adapter-specific normalization issue; it was the absence of a recursion-depth constraint in formDataToJSON. The added assertPathDepth check directly neutralizes that condition, and the regression test demonstrates the intended pre-overflow rejection behavior. Based on the supplied sources, this is a complete and technically appropriate remediation for the GHSA-described DoS vector.

Sources