CVE-2026-114143
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.
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
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 High
CVSS: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 High
CVSS: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), repositoryBinaryMuse/toml-node - Functions:
assign(),deepRef(),setNestedKey()inlib/compiler.js - Confirmed present in the audited checkout at commit
1b2ac40(2026-07-16), one commit past thev5.0.0tag (a changelog-only change) — i.e. present inv5.0.0, the latest release. Not exhaustively verified against every prior release, but the affected functions are unrelated tov5.0.0's BigInt/Temporal changes (perCHANGELOG.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 likea.b.c = 1.deepRef()(lines 247-281, the sink at line 252): the identical pattern viapathKey(keys.slice(0, i + 1))— reached from table headers[a.b.c]and array-of-tables[[a.b.c]]viasetPath()/addTableArray().setNestedKey()(lines 184-202, the sink at line 187): the identical pattern — reached from inline-table dotted keys liket = { 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 High
CVSS: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 High
CVSS: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 High
CVSS: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), repositoryBinaryMuse/toml-node - Functions:
assign(),deepRef(),setNestedKey()inlib/compiler.js - Confirmed present in the audited checkout at commit
1b2ac40(2026-07-16), one commit past thev5.0.0tag (a changelog-only change) — i.e. present inv5.0.0, the latest release. Not exhaustively verified against every prior release, but the affected functions are unrelated tov5.0.0's BigInt/Temporal changes (perCHANGELOG.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 likea.b.c = 1.deepRef()(lines 247-281, the sink at line 252): the identical pattern viapathKey(keys.slice(0, i + 1))— reached from table headers[a.b.c]and array-of-tables[[a.b.c]]viasetPath()/addTableArray().setNestedKey()(lines 184-202, the sink at line 187): the identical pattern — reached from inline-table dotted keys liket = { 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 High
CVSS: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
| Package | Affected | Fixed |
|---|---|---|
tomlnpm |
through 5.0.0 | 5.0.1 |
tomlTuxCare: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 |
tomlTuxCare: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 |
tomlnpm |
before 5.0.1 | 5.0.1 |
tomlRoot:npm |
before 3.0.0-aikido.2 | 3.0.0-aikido.24.2.0-aikido.1 |
@rootio/tomlRoot:npm |
before 3.0.0-root.io.2 | 3.0.0-root.io.24.2.0-root.io.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE 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
github.com/BinaryMuse/toml-node/security/advisories/GHSA-9j65-hcg3-gc64
github.com/BinaryMuse/toml-node/commit/609c873fffea0a27ebe5b4dd098eed2b3daf3606
github.com/BinaryMuse/toml-node/releases/tag/v5.0.1
nvd.nist.gov/vuln/detail/CVE-2026-114143
github.com/advisories/GHSA-9j65-hcg3-gc64
github.com/CVEProject/cvelistV5/tree/main/cves/2026/114xxx/CVE-2026-114143.json
github.com/BinaryMuse/toml-node
Left out here: the rest of 2 source descriptions. The JSON record has them.