Safeguard
Security

How Secure Is js-cookie? A Practical Security Guide

js-cookie is a tiny, popular cookie helper, but a 2026 attribute-injection flaw shows why the library needs the same scrutiny as any other dependency. Here is what to watch.

Aisha Rahman
Security Analyst
7 min read

js-cookie is safe to use as long as you keep it patched and never trust cookie attributes that come from user or backend-controlled JSON. The library itself is small, dependency-free, and widely deployed, but its job — reading and writing browser cookies from JavaScript — sits right on the boundary between your frontend and the browser's most sensitive storage. That makes how you call it more important than the library's line count. This guide covers what js-cookie does, the real vulnerability that landed in early 2026, and the configuration mistakes that turn a harmless helper into a session-hijacking surface.

What js-cookie actually does

js-cookie is a lightweight wrapper around document.cookie. Instead of parsing that awkward semicolon-delimited string by hand, you call Cookies.set('name', 'value', { expires: 7, secure: true }) and read it back with Cookies.get('name'). It handles URL encoding, expiration math, and JSON serialization so you do not have to. The js cookie API is deliberately tiny — set, get, remove, plus withAttributes and withConverter for reuse — which is a big part of why it has stuck around.

You install it the usual way. If you search for npm js-cookie or js-cookie npm you will land on the package page maintained by the js-cookie GitHub organization:

npm install js-cookie

At more than 14 million weekly downloads, it is one of the most depended-upon client-side utilities on the registry, which is exactly why its security behavior matters to so many teams who never think about it directly.

Is js-cookie a security risk by itself?

The core library does not touch the network, spawn processes, or read the filesystem, so its intrinsic attack surface is narrow. The risk is not that js-cookie does something malicious; it is that cookies are a high-value target and the library is the tool you use to set the flags that protect them. If you write a session token to a cookie without secure and sameSite, that is a session-fixation and cross-site-request problem regardless of which library set the cookie. js-cookie gives you the knobs; leaving them at their defaults is where teams get hurt.

There is also the supply-chain angle that applies to every npm dependency. A popular, low-churn package is an attractive account-takeover target, as the 2025 npm maintainer-phishing incidents made clear across the ecosystem. Pinning the version in your lockfile and running npm ci rather than npm install in CI keeps a compromised republish from silently entering your build.

The 2026 cookie-attribute-injection flaw (CVE-2026-46625)

In early 2026 the maintainers published an advisory (GHSA-qjx8-664m-686j, tracked as CVE-2026-46625, CVSS 7.5) describing a per-instance prototype hijack in the internal assign() helper. When an application forwards a JSON-derived object as the attributes argument to Cookies.set(), Cookies.remove(), Cookies.withAttributes(), or Cookies.withConverter(), the helper's for...in enumeration combined with direct property assignment could be steered through the __proto__ setter. The practical result was cookie-attribute injection: an attacker who controlled that JSON could set domain, secure, samesite, expires, or path on cookies the developer believed were locked down.

The dangerous pattern is the one that looks perfectly reasonable:

// Attributes come from a backend response the attacker can influence.
const cfg = await fetch('/config').then((r) => r.json());
Cookies.set('session', token, cfg.cookieAttrs);

If cfg.cookieAttrs is attacker-influenced, the injected attributes can weaken or relocate the cookie. Versions 3.0.5 and earlier are affected; the fix landed in 3.0.7 (with 3.0.6 adding partial hardening). The remediation is a one-line bump:

npm install js-cookie@^3.0.7

An SCA tool such as Safeguard can flag this transitively — the case where js-cookie is not in your package.json but arrives three layers down through a UI component library you did install. That indirect path is where version-based scanners earn their keep.

Setting cookies the right way with js-cookie

Most real-world js-cookie bugs are configuration bugs, not library bugs. Four attributes carry almost all of the security weight:

Cookies.set('session', token, {
  secure: true,      // only sent over HTTPS
  sameSite: 'strict', // blocks cross-site sending, kills most CSRF
  expires: 1,        // short lifetime, in days
  path: '/',         // scope narrowly
});

A few rules that hold up in practice:

  • Never store a session token that must be invisible to JavaScript in a js-cookie-managed cookie at all. js-cookie cannot set HttpOnly — by design, because HttpOnly cookies are unreadable from JavaScript. If a cookie needs HttpOnly, set it from the server. Storing an auth token where any injected script can read it is the root cause of most XSS-to-account-takeover chains.
  • Always set secure in production. Without it, the cookie rides along on any accidental HTTP request and is exposed to network attackers.
  • Prefer sameSite: 'strict' or 'lax'. This is your cheapest CSRF defense.
  • Do not pass externally sourced objects straight into the attributes argument, especially on versions before 3.0.7. Build the attributes object yourself from a fixed allowlist of keys.

Auditing js-cookie in an existing codebase

Start by finding every call site, because the risk lives in how the API is used:

grep -rn "Cookies\.\(set\|withAttributes\|withConverter\)" src/

For each set, confirm secure and sameSite are present and that the value is not a secret that belongs in an HttpOnly server cookie. Then check the installed version against the advisory:

npm ls js-cookie

If you see anything at or below 3.0.5, schedule the bump. If js-cookie shows up only as a transitive dependency, use npm ls js-cookie to trace which direct dependency pulled it in and update that parent, or add an override in package.json to force the patched version. Broader guidance on this kind of triage lives in our 10 npm security best practices writeup.

When you might not need js-cookie at all

For simple flags, modern browsers give you the CookieStore API, and for anything that must survive as an HttpOnly credential, the cookie should be set by your server with a Set-Cookie header, not by client JavaScript. js-cookie shines for non-sensitive client-side preferences — theme choice, dismissed-banner flags, A/B bucket — where readability from JavaScript is a feature, not a liability. Matching the tool to the sensitivity of the data is the whole game: keep secrets server-side and HttpOnly, keep js-cookie for the harmless stuff, and keep it patched.

FAQ

Is js-cookie safe to use in 2026?

Yes, on version 3.0.7 or later and used correctly. Upgrade off any release at or below 3.0.5 to close CVE-2026-46625, and never write secrets that need HttpOnly to a client-readable cookie.

What is the latest version of js-cookie on npm?

The 3.x line is current, and 3.0.7 is the version that contains the fix for the attribute-injection advisory. Always confirm against the npm page and pin the exact version in your lockfile.

Can js-cookie set an HttpOnly cookie?

No. HttpOnly cookies are, by definition, invisible to JavaScript, and js-cookie runs in JavaScript. Any cookie that must be HttpOnly has to be set by the server via the Set-Cookie response header.

How do I know if js-cookie is a transitive dependency in my project?

Run npm ls js-cookie. It prints the dependency tree path to every copy, so you can see which direct dependency introduced it and update the parent or add a version override.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.