Every CVE Search/ Get API key

CVE-2026-114143

toml-node: Quadratic-complexity DoS via long dotted keys or table paths in toml.parse()

8.7 HighFix available

toml-node is a TOML parser for Node.js and the browser. Prior to 5.0.1, toml.parse() repeatedly slices and rejoins every path prefix in lib/compiler.js while processing long dotted keys, table headers, array-of-tables headers, and inline-table keys in assign(), deepRef(), and setNestedKey(). The resulting quadratic work can block the Node.js event loop for several seconds, and sufficiently long paths can terminate the process through memory exhaustion. The maxDepth option does not limit key-segment count and therefore does not mitigate this path. This issue is fixed in version 5.0.1.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
None
Availability
High

Exploit likelihood

0.47%Up 0.2 points since Oct 22, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.7

toml-node: Quadratic-complexity DoS via long dotted keys or table paths in toml.parse()

toml-node is a TOML parser for Node.js and the browser. Prior to 5.0.1, toml.parse() repeatedly slices and rejoins every path prefix in lib/compiler.js while processing long dotted keys, table headers, array-of-tables headers, and inline-table keys in assign(), deepRef(), and setNestedKey(). The resulting quadratic work can block the Node.js event loop for several seconds, and sufficiently long paths can terminate the process through memory exhaustion. The maxDepth option does not limit key-segment count and therefore does not mitigate this path. This issue is fixed in version 5.0.1.

Record
CVE-2026-114143
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-407
Updated
2026-11-02
EUVDEUVD-2026-107555 8.7

toml-node is a TOML parser for Node.js and the browser. Prior to 5.0.1, toml.parse() repeatedly slices and rejoins every path prefix in lib/compiler.js while processing long dotted keys, table headers, array-of-tables headers, and inline-table keys in assign(), deepRef(), and setNestedKey(). The resulting quadratic work can block the Node.js event loop for several seconds, and sufficiently long paths can terminate the process through memory exhaustion. The maxDepth option does not limit key-segment count and therefore does not mitigate this path. This issue is fixed in version 5.0.1.

Record
EUVD-2026-107555
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-9j65-hcg3-gc64 8.7

toml-node: Quadratic-complexity DoS via long dotted keys or table paths in toml.parse()

Summary

toml.parse() is vulnerable to a quadratic-complexity (O(n²)) denial-of-service via a single long dotted key, table header, or inline-table key. A ~100KB crafted document causes a multi-second synchronous hang; a ~200KB document crashes the Node.js process outright with an uncatchable out-of-memory error. This is a separate, unpatched code path from the previously fixed stack-overflow DoS (GHSA-82x6-q7mm-w9cf) — it requires no array/inline-table nesting at all, and is confirmed unaffected by the maxDepth option that fixed that earlier issue.

Affected component / version

  • Package: toml (npm), repository BinaryMuse/toml-node
  • Functions: assign(), deepRef(), setNestedKey() in lib/compiler.js
  • Confirmed present in the audited checkout at commit 1b2ac40 (2026-07-16), one commit past the v5.0.0 tag (a changelog-only change) — i.e. present in v5.0.0, the latest release. Not exhaustively verified against every prior release, but the affected functions are unrelated to v5.0.0's BigInt/Temporal changes (per CHANGELOG.md), so the defect likely predates that release as well.

Details

toml.parse(input, options) (index.js:5-9) forwards the caller-supplied string to parser.parse() and then compiler.compile() with no length or structural validation. Inside lib/compiler.js, three separate functions each walk a dotted key's segments in a for loop and, on every iteration, recompute the full path-prefix string from scratch:

  • assign() (lines 69-107, the sink at line 81): var intermediatePath = makeFullPath(keys.slice(0, i + 1)); — reached for top-level dotted-key assignments like a.b.c = 1.
  • deepRef() (lines 247-281, the sink at line 252): the identical pattern via pathKey(keys.slice(0, i + 1)) — reached from table headers [a.b.c] and array-of-tables [[a.b.c]] via setPath()/addTableArray().
  • setNestedKey() (lines 184-202, the sink at line 187): the identical pattern — reached from inline-table dotted keys like t = { a.b.c = 1 }.

keys.slice(0, i + 1) allocates a new array of length i; pathKey()/makeFullPath() (lines 311-317) then does .map(quoteDottedString).join("."), also O(i). Since this runs on every one of the n segments of a dotted key, total work is O(1 + 2 + ... + n) = O(n²), not O(n). The string is computed unconditionally on the happy path (only ever used if an error is about to be thrown), so there is no early exit that makes this cheap in practice.

No limit exists anywhere on dotted-key segment count: dot_ended_table_key_part+ and inline_dot_key_part+ in src/toml.pegjs (lines 122, 311) are unbounded + repetitions, parsed iteratively rather than through the grammar's value rule — so the existing MAX_DEPTH/maxDepth nesting guard (src/toml.pegjs:141-151, enforced in the generated lib/parser.js:1022) does not apply to key length at all. We confirmed this directly: setting options.maxDepth: 1 (the strictest possible value) against a 16,000-segment key produced no measurable timing difference from the unrestricted case.

Proof of Concept

const toml = require('toml');

// n-segment dotted key: "k0.k1.k2. ... .k{n-1} = 1"
function segKey(n) {
  const parts = [];
  for (let i = 0; i < n; i++) parts.push('k' + i);
  return parts.join('.') + ' = 1\n';
}

// ~100.9 KB input -- takes ~6.6-6.8 seconds
toml.parse(segKey(16000));

// ~200 KB input -- crashes the Node process:
// "FATAL ERROR: Ineffective mark-compacts near heap limit - JavaScript heap out of memory"
toml.parse(segKey(32000));

Measured timings (Node v22, direct execution against this repo):

| n (segments) | input size | time | |---|---|---| | 1,000 | ~4.9 KB | 34 ms | | 8,000 | ~46.9 KB | 1.6 s | | 16,000 | ~100.9 KB | 6.8 s | | 32,000 | ~200 KB | process crash (OOM) |

Doubling n from 8,000→16,000 roughly quadruples runtime (~4.2x), the signature of O(n²) rather than the expected O(n) (~2x).…

Record
GHSA-9j65-hcg3-gc64
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-407
Updated
2026-11-02
NVD 8.7

toml-node is a TOML parser for Node.js and the browser. Prior to 5.0.1, toml.parse() repeatedly slices and rejoins every path prefix in lib/compiler.js while processing long dotted keys, table headers, array-of-tables headers, and inline-table keys in assign(), deepRef(), and setNestedKey(). The resulting quadratic work can block the Node.js event loop for several seconds, and sufficiently long paths can terminate the process through memory exhaustion. The maxDepth option does not limit key-segment count and therefore does not mitigate this path. This issue is fixed in version 5.0.1.

Record
CVE-2026-114143
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-407
Updated
2026-11-02
OSV 8.7

toml-node: Quadratic-complexity DoS via long dotted keys or table paths in toml.parse()

toml-node is a TOML parser for Node.js and the browser. Prior to 5.0.1, toml.parse() repeatedly slices and rejoins every path prefix in lib/compiler.js while processing long dotted keys, table headers, array-of-tables headers, and inline-table keys in assign(), deepRef(), and setNestedKey(). The resulting quadratic work can block the Node.js event loop for several seconds, and sufficiently long paths can terminate the process through memory exhaustion. The maxDepth option does not limit key-segment count and therefore does not mitigate this path. This issue is fixed in version 5.0.1.

Record
CVE-2026-114143
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-407
Updated
2026-11-02
OSVGHSA-9j65-hcg3-gc64 8.7

toml-node: Quadratic-complexity DoS via long dotted keys or table paths in toml.parse()

Summary

toml.parse() is vulnerable to a quadratic-complexity (O(n²)) denial-of-service via a single long dotted key, table header, or inline-table key. A ~100KB crafted document causes a multi-second synchronous hang; a ~200KB document crashes the Node.js process outright with an uncatchable out-of-memory error. This is a separate, unpatched code path from the previously fixed stack-overflow DoS (GHSA-82x6-q7mm-w9cf) — it requires no array/inline-table nesting at all, and is confirmed unaffected by the maxDepth option that fixed that earlier issue.

Affected component / version

  • Package: toml (npm), repository BinaryMuse/toml-node
  • Functions: assign(), deepRef(), setNestedKey() in lib/compiler.js
  • Confirmed present in the audited checkout at commit 1b2ac40 (2026-07-16), one commit past the v5.0.0 tag (a changelog-only change) — i.e. present in v5.0.0, the latest release. Not exhaustively verified against every prior release, but the affected functions are unrelated to v5.0.0's BigInt/Temporal changes (per CHANGELOG.md), so the defect likely predates that release as well.

Details

toml.parse(input, options) (index.js:5-9) forwards the caller-supplied string to parser.parse() and then compiler.compile() with no length or structural validation. Inside lib/compiler.js, three separate functions each walk a dotted key's segments in a for loop and, on every iteration, recompute the full path-prefix string from scratch:

  • assign() (lines 69-107, the sink at line 81): var intermediatePath = makeFullPath(keys.slice(0, i + 1)); — reached for top-level dotted-key assignments like a.b.c = 1.
  • deepRef() (lines 247-281, the sink at line 252): the identical pattern via pathKey(keys.slice(0, i + 1)) — reached from table headers [a.b.c] and array-of-tables [[a.b.c]] via setPath()/addTableArray().
  • setNestedKey() (lines 184-202, the sink at line 187): the identical pattern — reached from inline-table dotted keys like t = { a.b.c = 1 }.

keys.slice(0, i + 1) allocates a new array of length i; pathKey()/makeFullPath() (lines 311-317) then does .map(quoteDottedString).join("."), also O(i). Since this runs on every one of the n segments of a dotted key, total work is O(1 + 2 + ... + n) = O(n²), not O(n). The string is computed unconditionally on the happy path (only ever used if an error is about to be thrown), so there is no early exit that makes this cheap in practice.

No limit exists anywhere on dotted-key segment count: dot_ended_table_key_part+ and inline_dot_key_part+ in src/toml.pegjs (lines 122, 311) are unbounded + repetitions, parsed iteratively rather than through the grammar's value rule — so the existing MAX_DEPTH/maxDepth nesting guard (src/toml.pegjs:141-151, enforced in the generated lib/parser.js:1022) does not apply to key length at all. We confirmed this directly: setting options.maxDepth: 1 (the strictest possible value) against a 16,000-segment key produced no measurable timing difference from the unrestricted case.

Proof of Concept

const toml = require('toml');

// n-segment dotted key: "k0.k1.k2. ... .k{n-1} = 1"
function segKey(n) {
  const parts = [];
  for (let i = 0; i < n; i++) parts.push('k' + i);
  return parts.join('.') + ' = 1\n';
}

// ~100.9 KB input -- takes ~6.6-6.8 seconds
toml.parse(segKey(16000));

// ~200 KB input -- crashes the Node process:
// "FATAL ERROR: Ineffective mark-compacts near heap limit - JavaScript heap out of memory"
toml.parse(segKey(32000));

Measured timings (Node v22, direct execution against this repo):

| n (segments) | input size | time | |---|---|---| | 1,000 | ~4.9 KB | 34 ms | | 8,000 | ~46.9 KB | 1.6 s | | 16,000 | ~100.9 KB | 6.8 s | | 32,000 | ~200 KB | process crash (OOM) |

Doubling n from 8,000→16,000 roughly quadruples runtime (~4.2x), the signature of O(n²) rather than the expected O(n) (~2x).…

Record
GHSA-9j65-hcg3-gc64
CVSS 4.0
8.7 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
Weakness
CWE-407
Updated
2026-11-02
OSVCLSA-2026-1793099957 No score

TuxCare security update for toml (2 CVEs)

TuxCare rebuilt toml to address 2 CVEs. Fixed in 3.0.0-tuxcare.2.

Record
CLSA-2026-1793099957
Updated
2026-11-02
OSVCLSA-2026-1793099990 No score

TuxCare security update for toml (3 CVEs)

TuxCare rebuilt toml to address 3 CVEs. Fixed in 4.3.0-tuxcare.1.

Record
CLSA-2026-1793099990
Updated
2026-11-02
OSVROOT-APP-NPM-CVE-2026-114143 No score

CVE-2026-114143 in toml - Patched by Root

Root has patched CVE-2026-114143 in the toml package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-114143
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
toml
npm
through 5.0.0
5.0.1
toml
TuxCare:npm
From an advisory covering 2 CVEs
3.0.0-tuxcare.0 up to 3.0.0-tuxcare.2, plus listed versions
3.0.03.0.0-tuxcare.1
3.0.0-tuxcare.2
toml
TuxCare:npm
From an advisory covering 3 CVEs
4.3.0-tuxcare.0 up to 4.3.0-tuxcare.1, plus listed versions
4.3.0
4.3.0-tuxcare.1
toml
npm
before 5.0.1
5.0.1
toml
Root:npm
before 3.0.0-aikido.2
3.0.0-aikido.24.2.0-aikido.1
@rootio/toml
Root:npm
before 3.0.0-root.io.2
3.0.0-root.io.24.2.0-root.io.1

History

History
RecordedChangedSources
affected, facts
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-114143 is a high vulnerability (CVSS 8.7) in Binarymuse Toml-node, published October 21, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.47%, the 41st percentile. Fixed in toml 5.0.1.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open