GHSA-325j-mg25-8q58: Critical severity npm/yayson vulnerability
Summary Store/LegacyStore key internal lookup tables by the type, id, and relationship names from a JSON:API document. Because these were plain objects, a document with type: "proto" writes onto Object.prototype, polluting every object in the process.
Severity Suggested CVSS v3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H (8.1). The guaranteed impact is process-wide DoS / logic corruption; escalation to authorization bypass or RCE is dependent on gadgets in the consuming application.
Affected / Patched - Affected: <= 4.2.0 (verified in 3.0.0 and 4.2.0; all 3.x and 4.x). - Patched: 4.3.0.
Details type is a string value, untouched by JSON.parse, and is used directly as an object key: js if (!models[type]) models[type] = {} // models["proto"] is Object.prototype → skipped if (!models[type][id]) models[type][id] = model // → Object.prototype[id] = model The attacker controls the polluted key (id) and value (the model, populated from attributes). Pollution persists for the process lifetime. The malicious type can also arrive via an included resource referenced by a relationship, bypassing any data.type allow-list. LegacyStore is additionally reachable when a configured types mapping resolves to "proto".
Proof of concept js const { Store } = require('yayson')() new Store().sync({ data: { type: 'proto', id: 'polluted', attributes: { x: 1 } } }) console.log(({}).polluted) // { x: 1, id: 'polluted' } ← Object.prototype polluted
Workarounds Reject documents whose type or relationship names are proto, constructor, or prototype, or run Node with --disable-proto=throw.
Fix Null-prototype lookup tables, rejection of proto/constructor/prototype as document-derived member names, Object.keys() iteration, and null-prototype normalization of caller-supplied caches.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/yaysonto a version that resolves this vulnerability.Fixed in 4.3.0 - Upgrade
Upgrade
yaysonto a version that resolves this vulnerability.Fixed in 4.3.0 - Configuration
Run the application with Node using `--disable-proto=throw` to prevent `__proto__`-related prototype pollution.
Node.js --disable-proto = throw - Configuration
Reject any JSON:API documents whose `type` is `__proto__`, `constructor`, or `prototype`, and also reject any relationship/resource-derived names that are `__proto__`, `constructor`, or `prototype`.
yayson (JSON:API document processing) document member name validation = reject __proto__/constructor/prototype
Event History
Frequently Asked Questions
Which installations should be treated as affected?
Applications using npm/yayson Store or LegacyStore in versions 3.x or 4.x through 4.2.0 are affected. Version 4.3.0 is patched.
What does an attacker need to supply to trigger the issue?
The application must process an attacker-controlled JSON:API document containing a resource with type set to "__proto__". The attacker can control the polluted property name through the resource id and the stored value through model attributes.
Does restricting data.type values prevent exploitation?
Not necessarily. A malicious resource can be delivered through an included resource referenced by a relationship, bypassing an allow-list applied only to data.type.
What is the practical impact after exploitation?
The pollution persists for the lifetime of the process and can cause process-wide denial of service or logic corruption. Authorization bypass or remote code execution depends on exploitable gadgets in the consuming application.