Sep 14, 2026·7 min read·3 visits
Unauthenticated remote prototype pollution in confetti yayson allows process-wide logic corruption, Denial of Service, or Remote Code Execution via structured JSON:API documents.
A critical prototype pollution vulnerability was discovered in the confetti yayson library prior to version 4.3.0. The library deserializes JSON:API structures into internal cache dictionaries mapped with standard JavaScript objects. An attacker can control the cache keys by supplying '__proto__' in properties like type or id, modifying the prototype of all JavaScript objects process-wide.
The vulnerability designated as CVE-2026-61534 is a critical prototype pollution flaw residing within the yayson NPM library, specifically in its primary deserialization engines: Store and LegacyStore. The yayson library is designed to parse and structure JSON:API compliant payloads, mapping flat resource structures into relational object-oriented representations. Under normal operational circumstances, a server application leverages this library to deserialize untrusted client payloads into internal database models or runtime business objects.
Because the library handles highly nested and relational JSON:API structures, it maintains internal dictionaries to index processed models, associate relationships, and define model schemas. Prior to version 4.3.0, the core data structures utilized for these mapping tables were initialized as standard JavaScript objects, which implicitly inherit properties and methods from Object.prototype. This architectural pattern creates an entry point for prototype pollution because the keys utilized for dictionary lookups are directly derived from values supplied within user-controlled payloads.
An attacker capable of sending structured JSON:API documents can inject properties specifically targeting the prototype chain of standard JavaScript objects. By placing values such as proto within key fields of the JSON:API specification—specifically within the type, id, or relationship name properties—the library inadvertently executes arbitrary property writes onto Object.prototype. The resulting pollution propagates process-wide, altering the behavior of every subsequent object instantiation within the Node.js runtime.
The root cause of CVE-2026-61534 is the insecure initialization and modification of internal lookup caches within both Store and LegacyStore classes. Specifically, the library initializes internal lookup maps, such as models and relations, using standard object literal notation ({}). In JavaScript, an object literal inherits properties from Object.prototype, which includes standard accessors and methods like proto, constructor, and toString.
During the deserialization process, yayson parses the JSON:API payload to build relationships and cache model instances. To dynamically structure the output models, the library retrieves the type field from the client-supplied JSON data and uses this value directly as a key in the internal models dictionary. For example, when executing models[type], if an attacker provides the value proto as the type, the expression resolves to models['proto']. Because models is a plain object, this key accesses its prototype object instead of creating an empty entry.
The critical vulnerability sink occurs when the deserializer attempts to assign the model instance to the cache using the structure models[type][idStr] = model. Since models['proto'] resolves directly to Object.prototype, the assignment translates to Object.prototype[idStr] = model. This step successfully injects the attacker-controlled model object directly into the global prototype chain. This vulnerability falls under the classification of CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes).
To understand the vulnerability on a code level, we analyze the legacy and modern stores before the patch. In src/yayson/store.ts pre-4.3.0, the models reference is initialized using options?.models ?? {}. When processing a resource, the code executes the following block:
if (hasId(model)) {
const idStr = String(model.id)
if (!models[type]) {
models[type] = {}
}
if (!models[type][idStr]) {
models[type][idStr] = model
}
}Because models is initialized as a plain object, models['proto'] is already a truthy value pointing to Object.prototype. As a result, the check !models[type] evaluates to false, and the code skips the initialization block, proceeding directly to assign models['proto'][idStr] = model.
The patch introduced a dedicated defensive module src/yayson/safe.ts which provides helper functions to initialize safe dictionaries and reject dangerous keys:
export function safeObject<T extends object>(): T {
return Object.create(null) as T
}
const UNSAFE_KEYS = new Set<string>(['__proto__', 'constructor', 'prototype'])
export function isUnsafeKey(key: string): boolean {
return UNSAFE_KEYS.has(key)
}By replacing standard object literals with Object.create(null), the resulting dictionary has no prototype properties. Thus, a lookup of models['proto'] evaluates to undefined, preventing any prototype resolution. Additionally, isUnsafeKey intercepts and rejects requests that attempt to use proto, constructor, or prototype during relationship configuration and property iteration.
Exploitation of CVE-2026-61534 requires sending a crafted JSON:API payload to a REST API endpoint that parses user input with a vulnerable version of yayson. The attack can be launched remotely without authentication, provided the endpoint is publicly exposed and does not validate schema types against a strict whitelist prior to invoking yayson deserialization.
The following diagram illustrates the flow of a successful prototype pollution attack via a vulnerable yayson parsing pipeline:
An attacker can perform the exploitation in a single HTTP request. If the target server deserializes the payload, the prototype chain of all subsequently created objects becomes polluted. For instance, if an attacker injects a property such as adminStatus with the value true, any code block checking if (user.adminStatus) on objects that lack this property will resolve to true, completely bypassing authorization controls.
Furthermore, prototype pollution can be leveraged to execute a Denial of Service (DoS) attack. By polluting fundamental object methods like toString or valueOf with a string or primitive value, the attacker can cause immediate application crashes. Whenever the runtime or an external module attempts to serialize or stringify any object, the engine will attempt to execute the polluted primitive as a function, resulting in an unhandled TypeError that terminates the Node.js process.
The impact of CVE-2026-61534 is classified as Critical, with a CVSS v3.1 score of 9.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H). While the immediate guaranteed consequence is Denial of Service or logic corruption, the vulnerability can serve as an entry point for Remote Code Execution (RCE) or complete authentication bypass. This depends on the specific libraries and frameworks loaded within the active Node.js process.
In complex modern applications, many utility frameworks (such as templating engines or database query builders) dynamically resolve options and configurations by searching object keys. If an attacker can inject properties into the global object prototype, they can alter the internal options of these libraries. For example, polluting templating options in engines like EJS or Pug has historically allowed attackers to execute arbitrary shell commands on the hosting system.
If the consuming application does not run within an environment containing usable RCE gadgets, the vulnerability still presents severe availability risks. Because Node.js is single-threaded, a single prototype pollution attack that crashes the process disrupts service for all active users. The severity of this impact is mitigated only by the necessity of specific application-level configurations or gadgets to achieve RCE, leading some analysts to propose an alternate high-severity rating of 8.1.
The primary and recommended mitigation is upgrading the yayson package to version 4.3.0 or higher. The maintainers addressed the issue by integrating null-prototype objects and introducing safe iteration mechanisms across all internal caches. This ensures that the prototype chain is isolated from any incoming payload keys.
If upgrading the package immediately is not feasible, security teams can implement network or runtime mitigations. At the runtime level, Node.js processes should be executed with the --disable-proto=throw command-line argument. This flag instructs the V8 engine to throw an exception immediately if any code attempts to access or modify the proto property, effectively blocking the exploitation attempt before it can pollute the global scope.
Additionally, an input validation middleware can be introduced at the application perimeter. This middleware should recursively sanitize all incoming JSON bodies, parsing keys and stripping any keys that match the blacklisted keywords: proto, constructor, and prototype. Implementing this defensive layer provides robust protection against prototype pollution across all parser libraries, not just yayson.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
yayson confetti | <= 4.2.0 | 4.3.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1321 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 9.1 (Critical) |
| Exploit Status | Proof of Concept (PoC) Available |
| CISA KEV Status | Not Listed |
| Impact | Integrity and Availability (High) |
The product receives input from an upstream component, but does not neutralize or incorrectly neutralizes the input before using it to modify the attributes of a prototype object.
An authentication bypass vulnerability in ESPHome Device Builder Dashboard allows unauthenticated remote attackers to gain administrative access. The flaw is caused by a backward compatibility break during an environment variable rename that silently disables dashboard authentication upon upgrade.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.