Skip to main content

valibot CVE-2026-59952

| EUVDEUVD-2026-50775 MEDIUM
Improper Handling of Exceptional Conditions (CWE-755)
2026-07-24 https://github.com/open-circle/valibot GHSA-5qjj-4xww-7phc
6.9
CVSS 4.0 · Vendor: https://github.com/open-circle/valibot
Share

Severity by source

Vendor (https://github.com/open-circle/valibot) PRIMARY
6.9 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/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
vuln.today AI
7.5 HIGH

Network accessible, low complexity, no privileges; high availability impact from crash.

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

Primary rating from Vendor (https://github.com/open-circle/valibot).

CVSS VectorVendor: https://github.com/open-circle/valibot

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

4
CVSS changed
Jul 30, 2026 - 01:22 NVD
6.9 (MEDIUM)
Source Code Evidence Fetched
Jul 26, 2026 - 12:14 vuln.today
Analysis Generated
Jul 26, 2026 - 12:14 vuln.today
CVE Published
Jul 24, 2026 - 16:14 cve.org
MEDIUM

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 280 npm packages depend on valibot (69 direct, 212 indirect)

Ecosystem-wide dependent count for version 1.4.2.

DescriptionCVE.org

Summary

valibot 1.4.1 can throw a TypeError inside its flatten() helper when validation issues contain attacker-controlled object keys such as toString, valueOf, or hasOwnProperty.

The issue is reachable through normal record() validation. record() intentionally filters __proto__, prototype, and constructor, but it still accepts other own keys that collide with inherited Object.prototype properties. If the record key schema or value schema rejects such an entry, Valibot creates an issue path containing that key. Passing the resulting issues to Valibot's documented flatten() helper causes flatErrors.nested[dotPath] to resolve to the inherited method instead of an own error array, and the helper calls .push(...) on that function.

This is not a global prototype pollution issue. The impact is availability/error handling: applications that validate user-controlled objects with record() and flatten validation errors for API responses can crash the request path with a TypeError instead of returning structured validation errors.

Affected package

  • Ecosystem: npm
  • Package: valibot
  • Affected version verified: 1.4.1
  • Fixed version: none known
  • Repository: open-circle/valibot
  • Current main ref tested by source review: 9bb6617

Root cause

record() uses _isValidObjectKey() before validating record entries. The helper blocks the three classic prototype pollution keys:

ts
key !== '__proto__' &&
key !== 'prototype' &&
key !== 'constructor'

It does not block other inherited Object.prototype names such as toString, valueOf, and hasOwnProperty. These remain valid own JSON object keys and can appear in issue paths when either the record key schema or value schema rejects the entry.

flatten() then creates nested error storage with an ordinary object:

ts
flatErrors.nested = {};

For a dot path such as toString, this check reads the inherited Object.prototype.toString function:

ts
if (flatErrors.nested![dotPath]) {
  flatErrors.nested![dotPath]!.push(issue.message);
}

Because the inherited function is truthy, flatten() calls .push(...) on a function and throws TypeError: flatErrors.nested[dotPath].push is not a function.

Impact

A remote attacker can trigger this if an application:

  1. validates attacker-controlled JSON objects with v.record(...);
  2. receives an invalid key or invalid value under a key such as toString;
  3. uses Valibot's flatten(result.issues) helper to prepare validation errors.

This is a common pattern in API/form validation: safeParse() collects issues and flatten() converts them into response-friendly error objects. Instead of a validation response, the request can hit an unexpected exception path.

The same root cause can also affect manually constructed issues or other schemas that place inherited Object property names into dot paths. I am reporting the record() path because it uses only public Valibot APIs and attacker-controlled JSON keys.

Local reproduction

Run in a disposable directory:

bash
npm install valibot@1.4.1
node poc_record_flatten_inherited_key_dos.mjs

Minimal example:

js
import * as v from 'valibot';

const schema = v.record(v.string(), v.number());
const input = JSON.parse('{"toString":"not-a-number"}');

const result = v.safeParse(schema, input);
console.log(result.success); // false
console.log(result.issues[0].path.map((item) => item.key)); // ["toString"]

v.flatten(result.issues); // TypeError

Observed output from valibot@1.4.1:

json
{
  "name": "record value schema rejects attacker-controlled value",
  "key": "toString",
  "success": false,
  "issueCount": 1,
  "firstPath": ["toString"],
  "firstMessage": "Invalid type: Expected number but received \"not-a-number\"",
  "flattened": {
    "ok": false,
    "exception": "TypeError",
    "message": "flatErrors.nested[dotPath].push is not a function"
  }
}

The local PoC also reproduces the same exception for valueOf, hasOwnProperty, isPrototypeOf, propertyIsEnumerable, and toLocaleString. A control case with an ordinary key produces normal flattened errors.

Duplicate checks performed before submission

  • npm metadata confirmed current valibot release is 1.4.1 and maps to open-circle/valibot.
  • gh api repos/open-circle/valibot/private-vulnerability-reporting returned {"enabled":true}.
  • npm audit for a clean project containing only valibot@1.4.1 returned no vulnerabilities.
  • Repository advisories and the GitHub Advisory Database only returned the historical emoji ReDoS advisory fixed in 1.2.0.
  • OSV exact-version query for npm valibot 1.4.1 returned no vulnerabilities.
  • Public issue/PR searches for flatten toString, flatten hasOwnProperty, record toString, __proto__, constructor, and prototype pollution did not find a matching disclosure of this record() issue-path / flatten() exception.
  • Reviewed related public PRs: open-circle/valibot#67 added prototype pollution mitigation for record() by blacklisting __proto__, prototype, and constructor; it does not cover flatten() collisions with other inherited property names. open-circle/valibot#1429 is an open plain-object / record() type semantics PR and does not disclose this flatten() exception behavior.

Suggested remediation

Use null-prototype containers for flat error maps and/or perform own-property checks before appending:

  • Initialize flatErrors.nested as Object.create(null).
  • Check nested entries with Object.prototype.hasOwnProperty.call(flatErrors.nested, dotPath) rather than truthiness.
  • Consider filtering or escaping unsafe dot path segments in getDotPath() / flatten(), including inherited Object property names.
  • Add regression tests for flatten() with paths toString, valueOf, hasOwnProperty, __proto__, prototype, and constructor.
  • Consider using the same hardening for other accumulator objects that store attacker-controlled keys.

AnalysisAI

Denial of service in valibot's flatten() helper can be triggered by attacker-controlled object keys like 'toString' or 'valueOf' when used with record() validation. An unauthenticated remote attacker can submit crafted JSON to an API that validates input via valibot's record() schema and then calls flatten() on the resulting issues, causing a TypeError that crashes the request path instead of returning structured errors. A public proof-of-concept is available, and the vendor has released a patch in version 1.4.2.

Technical ContextAI

The vulnerability arises from improper handling of the JavaScript object prototype chain in valibot's flatten() method. When valibot's record() schema validates user-supplied JSON, it can generate validation issues with paths that include the keys of the JSON object. If a key happens to be an inherited property name from Object.prototype (e.g., 'toString', 'valueOf', 'hasOwnProperty'), the dot path constructed by flatten() resolves to the inherited function object instead of an expected own-property error array. The code then attempts to call .push() on that function, throwing a TypeError. The root cause is the use of a plain object {} for nested error storage without a null prototype or proper own-property checks, exposing a collision with prototype chain members. CWE-755: Improper Handling of Exceptional Conditions.

RemediationAI

Upgrade valibot to version 1.4.2 or later. The fix changes the nested error property check to use Object.prototype.hasOwnProperty.call(), as shown in commit 1bd01c304657cd0809cc92694360b6cc60f700bf. If immediate upgrade is not possible, avoid calling flatten() on validation results derived from untrusted input, or sanitize issue paths to strip keys that match Object.prototype properties. However, the most reliable mitigation is patching the library.

CVE-2024-41713 CRITICAL POC
9.1 Oct 21

A vulnerability in the NuPoint Unified Messaging (NPM) component of Mitel MiCollab through 9.8 SP1 FP2 (9.8.1.201) could

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2023-44487 HIGH POC
7.5 Oct 10

Denial of service against HTTP/2 server implementations allows remote unauthenticated attackers to exhaust server resour

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2016-2107 MEDIUM POC
5.9 May 05

The AES-NI implementation in OpenSSL before 1.0.1t and 1.0.2 before 1.0.2h does not consider memory allocation during a

Share

CVE-2026-59952 vulnerability details – vuln.today

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