CVE-2025-6545 — pbkdf2
Fix: browserify/pbkdf2@9699045CVE-2025-6545 is a Improper Input Validation vulnerability in pbkdf2. A fix is available for pbkdf2 — see the affected versions and patch details below.
pbkdf2 silently returns predictable uninitialized/zero-filled memory for non-normalized or unimplemented algos supported by Node.js
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
Exploitation and automatability from CISA’s SSVC triage for CVE-2025-6545.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
pbkdf2npmDescription
Summary
This affects both:
- Unsupported algos (e.g.
sha3-256/sha3-512/sha512-256) - Supported but non-normalized algos (e.g.
Sha256/Sha512/SHA1/sha-1/sha-256/sha-512)
All of those work correctly in Node.js, but this polyfill silently returns highly predictable ouput
Under Node.js (only with pbkdf2/browser import, unlikely) / Bun (pbkdf2 top-level import is affected), the memory is not zero-filled but is uninitialized, as Buffer.allocUnsafe is used
Under browsers, it just returns zero-filled buffers (Which is also critical, those are completely unacceptable as kdf output and ruin security)
Were you affected?
The full list of arguments that were not affected were literal:
'md5''sha1''sha224''sha256''sha384''sha512''rmd160''ripemd160'
Any other arguments, e.g. representation variations of the above ones like 'SHA-1'/'sha-256'/'SHA512' or different algos like 'sha3-512'/'blake2b512', while supported on Node.js crypto module, returned predictable output on pbkdf2 (or crypto browser/bundlers polyfill)
Beware of packages re-exporting this under a different signature, like (abstract):
const crypto = require('crypto')
module.exports.deriveKey = (algo, pass, salt) => crypto.pbkdf2Sync(pass, salt, 2048, 64, algo)
In this case, the resulting deriveKey method is also affected (to the same extent / conditions as listed here).
Environments
This affects require('crypto') in polyfilled mode (e.g. from crypto-browserify, node-libs-browser, vite-plugin-node-polyfills, node-stdlib-browser, etc. -- basically everything that bundles/polfyills crypto
- In bundled code (e.g. Webpack / Vite / whatever), this affects
require('crypto')andrequire('pbkdf2') - On Node.js, this does not affect
require('pbkdf2')(orrequire('crypto')obviously), but affectsrequire('pbkdf2/browser') - On Bun, this does affect
require('pbkdf2')andrequire('pbkdf2/browser')(and returns uninitialized memory, often zeros / sparse flipped bytes)
PoC
const node = require('crypto')
const polyfill = require('pbkdf2/browser')
const algos = [
'sha3-512', 'sha3-256', 'SHA3-384',
'Sha256', 'Sha512', 'sha512-256',
'SHA1', 'sha-1',
'blake2b512',
'RMD160', 'RIPEMD-160', 'ripemd-160',
]
for (const algo of algos) {
for (const { pbkdf2Sync } of [node, polyfill]) {
const key = pbkdf2Sync('secret', 'salt', 100000, 64, algo)
console.log(`${algo}: ${key.toString('hex')}`);
}
}
Output (odd lines are Node.js, even is pbkdf2 module / polyfill):
sha3-512: de00370414a3251d6d620dc8f7c371644e5d7f365ab23b116298a23fa4077b39deab802dd61714847a5c7e9981704ffe009aee5bb40f6f0103fc60f3d4cedfb0
sha3-512: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sha3-256: 76bf06909b91e4c968700078ee36af92019d0839ab1fea2f345c6c8685074ca0179302633fbd84d22cff4f8744952b2d07edbfc9658e95d30fb4e93ee067c7c9
sha3-256: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
SHA3-384: 2b2b41b73f9b7bcd023f709ea84ba3c29a88edc311b737856ba9e74a2d9a928f233eb8cb404a9ba93c276edf6380c692140024a0bc12b75bfa38626207915e01
SHA3-384: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sha256: 3fa094211c0cf2ed1d332ab43adc69aab469f0e0f2cae6345c81bb874eef3f9eb2c629052ec272ca49c2ee95b33e7ba6377b2317cd0dacce92c4748d3c7a45f0
Sha256: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sha512: 3745e482c6e0ade35da10139e797157f4a5da669dad7d5da88ef87e47471cc47ed941c7ad618e827304f083f8707f12b7cfdd5f489b782f10cc269e3c08d59ae
Sha512: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sha512-256: e423f61987413121418715d0ebf64cb646042ae9a09fe4fd2c764a4f186ba28cf70823fdc2b03dda67a0d977c6f0a0612e5ed74a11e6f32b033cb658fa9f270d
sha512-256: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
SHA1: 0e24bc5a548b236e3eb3b22317ef805664a88747c725cd35bfb0db0e4ae5539e3ed5cd5ba8c0ac018deb6518059788c8fffbe624f614fbbe62ba6a6e174e4a72
SHA1: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
sha-1: 0e24bc5a548b236e3eb3b22317ef805664a88747c725cd35bfb0db0e4ae5539e3ed5cd5ba8c0ac018deb6518059788c8fffbe624f614fbbe62ba6a6e174e4a72
sha-1: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
blake2b512: d3d661100c5ffb79bdf3b5c77d1698e621414cba40e2348bd3f1b10fbd2fe97bff4dc7d76474955bfefa61179f2a37e9dddedced0e7e79ef9d8c678080d45926
blake2b512: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
RMD160: ec65dbad1485616cf0426725d64e009ad3e1633543746ccb56b7f06eb7ce51d0249aaef27c879f32911a7c0accdc83389c2948ddec439114f6165366f9b4cca2
RMD160: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
RIPEMD-160: ec65dbad1485616cf0426725d64e009ad3e1633543746ccb56b7f06eb7ce51d0249aaef27c879f32911a7c0accdc83389c2948ddec439114f6165366f9b4cca2
RIPEMD-160: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ripemd-160: ec65dbad1485616cf0426725d64e009ad3e1633543746ccb56b7f06eb7ce51d0249aaef27c879f32911a7c0accdc83389c2948ddec439114f6165366f9b4cca2
ripemd-160: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Uninitialized memory
const { pbkdf2Sync } = require('pbkdf2/browser') // or just 'pbkdf2' on Bun will do this too
let prev
for (let i = 0; i < 100000; i++) {
const key = pbkdf2Sync('secret', 'salt', 100000, 64, 'sha3-256')
const hex = key.toString('hex')
if (hex !== prev) console.log(hex);
prev = hex
}
Affected versions
Seems to be since https://github.com/browserify/pbkdf2/commit/9699045c37a07f8319cfb8d44e2ff4252d7a7078
Impact
This is critical, browserifying code might silently generate zero-filled keys instead of proper ones, for code that was working on Node.js or in test environment
Just updating to a fixed version is not enough: if anyone was using pbkdf2 lib (e.g. via crypto-browserify or directly) on algos not from the literal string list (see "were you affected"), recheck where those keys went / how they were used, and take action accordingly
Note
Most likely, you receive this either through a subdep using pbkdf2 module directly (and then it is used), or through crypto-browserify (and the usage depends on whether you or any of your subdeps were calling pbkdf2/pbkdf2Sync methods from Node.js crypto inside your bundle)
When targeting non-Node.js, prever avoiding Node.js crypto polyfill at all, and use crypto.subtle and/or modern/audited cryptography primitives instead
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | pbkdf2 | ≥ 3.0.10&&< 3.1.3 | 3.1.3npm install pbkdf2@3.1.3 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for pbkdf2, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update pbkdf2 to 3.1.3 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-6545 is resolved across your whole dependency graph.
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.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2025-6545 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2025-6545. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
This flaw is rated important because it causes the pbkdf2 module to quietly return weak or zero-filled keys when certain algorithm names are used incorrectly in browsers or bundled code, this causes the function to silently return a predictable value (such as a zero-filled buffer or uninitialized memory) instead of a…
| Product | Fixed in | Advisory |
|---|---|---|
| Red Hat Developer Hub 1.7 | rhdh/rhdh-hub-rhel9:1.7.0-1754936470 | RHSA-2025:14090 |
| Red Hat OpenShift Pipelines 1.15 | openshift-pipelines/pipelines-hub-api-rhel8:1771425314 | RHSA-2026:3710 |
| Red Hat OpenShift Pipelines 1.15 | openshift-pipelines/pipelines-hub-api-rhel8:1771425314 | RHSA-2026:3712 |
| Red Hat OpenShift Pipelines 1.19 | openshift-pipelines/pipelines-hub-db-migration-rhel9:v1.19.4-1764819005 | RHSA-2025:22905 |
| Red Hat OpenShift Service Mesh 3.0 | openshift-service-mesh/kiali-ossmc-rhel9:2.4.7-1751549390 | RHSA-2025:10738 |
| Red Hat Trusted Artifact Signer 1.2 | rhtas/rekor-search-ui-rhel9:1.2.1-1755456740 | RHSA-2025:14474 |
Frequently Asked Questions
Is CVE-2025-6545 in your dependencies?
O3 Security finds CVE-2025-6545 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.