Skip to main content

js-toml CVE-2026-50029

MEDIUM
Incorrect Comparison (CWE-697)
2026-06-26 https://github.com/sunnyadn/js-toml GHSA-m34p-749j-x6m6
5.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
5.3 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
vuln.today AI
3.7 LOW

AC:H reflects that exploitation success depends on the host application using falsy TOML booleans for security gates, a condition outside attacker control.

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
None

Lifecycle Timeline

2
Source Code Evidence Fetched
Jun 26, 2026 - 23:16 vuln.today
Analysis Generated
Jun 26, 2026 - 23:16 vuln.today

DescriptionGitHub Advisory

Summary

js-toml's interpreter checks whether a key already exists in a parser-built container with if (object[key]) instead of if (key in object). When the prior value is a falsy primitive - false, 0, 0n, 0.0, -0, or "" - the duplicate-key branch is skipped and the value is silently overwritten by a later sub-table, dotted-key sub-table, or array-of-tables sharing the same name. Per the TOML 1.0.0 spec ("Defining a key multiple times is invalid"; "You cannot define any key or table more than once"), this should be a parse error.

The result is structural type confusion of attacker-named keys in the value returned by load(). A boolean-typed false (or numeric 0) becomes a truthy object. Host applications that gate behavior on if (config.flag), if (!user.banned), if (config.allowDelete), or if (config.publicMode) will silently take the truthy branch.

This is distinct from GHSA-65fc-cr5f-v7r2 (the 1.0.2 prototype-pollution fix). Object.prototype is not polluted. The Object.create(null) mitigation from 1.0.2 is intact; the bug here is in the duplicate-key state machine, not in container construction.

Details

Two truthy checks are wrong:

src/load/interpreter.ts:214 - Interpreter.tryCreatingObject

js
if (object[key]) {            // falsy primitives slip through
    // duplicate-key logic
} else {
    object[key] = createSafeObject();   // silently overwrites the prior falsy value
    ...
}

src/load/interpreter.ts:278 - Interpreter.getOrCreateArray

js
if (object[first] && !Array.isArray(object[first])) {   // same flaw
    throw new DuplicateKeyError();
}
object[first] = object[first] || [];   // overwrites the prior falsy value

Both should use the in operator. Containers are created via Object.create(null), so in is unambiguous (no inherited keys to worry about).

The bug is reachable through every parent-walking interpreter path:

  • assignValue - dotted keys in key = value
  • createTable - [stdTable] headers
  • getOrCreateArray - [[arrayOfTables]] headers

PoC

toml
isAdmin = false
[isAdmin]
forced = "yes"
js
import { load } from 'js-toml';

const config = load(`
isAdmin = false
[isAdmin]
forced = "yes"
`);

console.log(JSON.stringify(config));
// {"isAdmin":{"forced":"yes"}}

console.log(config.isAdmin ? 'BYPASS' : 'safe');
// BYPASS

if (config.isAdmin) {
  // attacker reaches admin-only code
}

Impact

Spec-violating input acceptance leading to structural type confusion. (CWE-697)

Suggested fix

in src/load/interpreter.ts

diff
export class Interpreter extends BaseCstVisitor {
     ignoreImplicitDeclared,
     ignoreExplicitDeclared
   ) {
-    if (object[key]) {
+    if (key in object) {
       if (
         !isPlainObject(object[key]) ||
         (!ignoreExplicitDeclared &&
diff
export class Interpreter extends BaseCstVisitor {
       return this.getOrCreateArray(keys, object[first], idx + 1);
     }

-    if (object[first] && !Array.isArray(object[first])) {
+    if (first in object && !Array.isArray(object[first])) {
       throw new DuplicateKeyError();
     }

     object[first] = object[first] || [];

AnalysisAI

Silent type confusion in js-toml's TOML interpreter allows attacker-controlled input to overwrite falsy primitive values (false, 0, empty string) with truthy objects, defeating duplicate-key enforcement required by TOML 1.0.0 spec. All versions of js-toml up to and including 1.1.1 are affected via the npm package (pkg:npm/js-toml). …

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Recon
Identify application accepting attacker-influenced TOML
Delivery
Craft TOML with falsy scalar then same-named sub-table
Exploit
Submit malicious TOML input
Install
js-toml skips duplicate-key check for falsy value
C2
Scalar overwritten with truthy object
Execute
Host application security gate evaluates truthy
Impact
Attacker gains unauthorized access

Vulnerability AssessmentAI

Exploitation Exploitation requires three concurrent conditions: (1) the attacker can supply or influence the TOML content that is parsed by js-toml - for example, a user-uploaded config file, a network-delivered configuration payload, or a TOML fragment embedded in attacker-controlled data; (2) the host application is running js-toml version 1.1.1 or earlier; (3) the host application gates security-relevant behavior on the truthiness of a TOML-parsed value that could legitimately be false, 0, 0n, -0, 0.0, or an empty string - specifically patterns like if (config.isAdmin), if (!user.banned), if (config.allowDelete), or if (config.publicMode). … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment The NVD-assigned CVSS 3.1 vector (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N, score 5.3 Medium) treats the flaw as low-complexity unauthenticated network exploitation with limited integrity impact. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario An attacker submits a crafted TOML document to an application that uses js-toml to parse user-supplied or attacker-influenced configuration. The document sets a security flag to false (isAdmin = false) and then defines a sub-table with the same name ([isAdmin] with an arbitrary key-value pair). …
Remediation Upgrade js-toml to version 1.1.2, which replaces both truthy checks (if (object[key]) and if (object[first] && ...)) with the correct in-operator membership tests in src/load/interpreter.ts. … Detailed patch versions, workarounds, and compensating controls in full report.

Threat intelligence, references, and detailed analysis are available after sign-in.

Share

CVE-2026-50029 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy