Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
📦 npm

GHSA-w48f-fwg7-ww6p

@stablelib/cbor: Prototype poisoning via `__proto__` map keys in CBOR decoding

Published
Apr 4, 2026
Updated
Apr 7, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed

Blast Radius

1 pkg affected
📦@stablelib/cbor

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.

Description

Summary

@stablelib/cbor decodes CBOR maps into ordinary JavaScript objects and assigns attacker-controlled keys directly onto those objects. A CBOR map key named __proto__ therefore changes the prototype of the decoded object instead of becoming an ordinary data property.

Details

The decoder builds map results with a plain {} and then stores attacker-controlled keys using bracket assignment.

That is unsafe for special property names. In JavaScript, assigning to obj["__proto__"] on a normal object does not create a plain own property. It invokes the built-in __proto__ setter and replaces the object’s prototype if the supplied value is an object or null.

As a result, a CBOR payload containing a map entry like:

  • key: "__proto__"
  • value: { isAdmin: true }

does not decode to an object with an own property called __proto__. It decodes to an object whose prototype is now attacker-controlled. Any code that later reads properties through normal lookup will see inherited attacker-supplied values.

PoC

import { decode } from "@stablelib/cbor";

// CBOR:
// {
//   "__proto__": { "isAdmin": true }
// }
//
// a1                    map(1)
//   69                  text(9)
//     "__proto__"
//   a1                  map(1)
//     67                text(7)
//       "isAdmin"
//     f5                true

const payload = new Uint8Array([
  0xa1,
  0x69, 0x5f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x5f,
  0xa1,
  0x67, 0x69, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e,
  0xf5
]);

const obj = decode(payload);

console.log(Object.hasOwn(obj, "isAdmin")); // false
console.log(obj.isAdmin);                   // true
console.log(Object.getPrototypeOf(obj).isAdmin); // true

Impact

Any application that decodes untrusted CBOR into JavaScript objects can receive objects with attacker-controlled prototypes.

In practice, that can corrupt configuration objects, influence authorization checks, alter feature flags, and break application logic that relies on normal property lookup instead of strict own-property checks. If the decoded object is later merged into other objects, the impact can spread further.

Solution

Upgrade to version 2.0.4.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@stablelib/cborall versions2.0.3

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @stablelib/cbor. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update @stablelib/cbor to 2.0.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-w48f-fwg7-ww6p is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-w48f-fwg7-ww6p is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-w48f-fwg7-ww6p. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary `@stablelib/cbor` decodes CBOR maps into ordinary JavaScript objects and assigns attacker-controlled keys directly onto those objects. A CBOR map key named `__proto__` therefore changes the prototype of the decoded object instead of becoming an ordinary data property. ### Details The decoder builds map results with a plain `{}` and then stores attacker-controlled keys using bracket assignment. That is unsafe for special property names. In JavaScript, assigning to `obj["__proto__"]` on a normal object does not create a plain own property. It invokes the built-in `__proto__` sett
O3 Security · Impact-Aware SCA

Is GHSA-w48f-fwg7-ww6p in your dependencies?

O3 detects GHSA-w48f-fwg7-ww6p across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.