Missing type checks leading to hash rewind and passing on crafted data
Description
Improper Input Validation vulnerability in sha.js allows Input Data Manipulation.This issue affects sha.js: through 2.4.11.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
sha.js through 2.4.11 lacks input type validation, allowing attackers to rewind hash state, cause collisions, or trigger denial of service.
Vulnerability
Overview
CVE-2025-9288 is an improper input validation vulnerability in the sha.jssha.js library (versions through 2.4.11). The library fails to enforce that inputs to the update() method are well-formed Buffer or string types. This allows arbitrary objects, such as those with a length` property set to a negative number or a very large number, to be processed, leading to undefined behavior [1][2].
Exploitation
An attacker can exploit this by providing crafted input objects to sha.js's update() method. For example, passing an object like {length: -3} can rewind the internal hash state, effectively, allowing an attacker to turn a tagged hash into an untagged hash. Similarly, providing {length: '1e99} as length can cause a denial of service (DoS) due to excessive resource consumption. The attack does not require authentication if the attacker can control the input to the hash function, which is common in many applications that hash user-supplied data [2].
Impact
Successful exploitation can lead to: - Hash state rewind: An attacker can manipulate the hash state to produce the same hash for different inputs, effectively creating collisions or bypassing hash-based integrity checks. - Value miscalculation: By crafting inputs with specific properties, an attacker can cause the hash to produce the same output for different data, leading to potential security bypasses in systems relying on hash uniqueness. - Denial of Service: Providing extremely large length values can cause the library to hang or crash, impacting availability [2].
Mitigation
The vulnerability affects all versions of sha.js up to and including 2.4.11. The fix has been implemented in commit f2a258e which adds input validation and throws errors on invalid types [3]. Users should update to a patched version (e.g., 2.4.12 or later) as soon as possible. No workaround is available other than upgrading.
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sha.jsnpm | < 2.4.12 | 2.4.12 |
Affected products
2v2.1.4, v2.1.5, v2.1.6, …+ 1 more
- (no CPE)range: v2.1.4, v2.1.5, v2.1.6, …
- (no CPE)range: <=2.4.11
Patches
1f2a258e9f2d0[Fix] support multi-byte wide typed arrays
4 files changed · +51 −9
.eslintrc+12 −0 modified@@ -60,5 +60,17 @@ "max-lines-per-function": "off", }, }, + { + "files": "hash.js", + "globals": { + "Uint8Array": false, + }, + }, + { + "files": "test/test.js", + "globals": { + "Uint16Array": false, + }, + }, ], }
hash.js+2 −4 modified@@ -1,6 +1,7 @@ 'use strict'; var Buffer = require('safe-buffer').Buffer; +var toBuffer = require('to-buffer'); // prototype class for hash functions function Hash(blockSize, finalSize) { @@ -12,10 +13,7 @@ function Hash(blockSize, finalSize) { Hash.prototype.update = function (data, enc) { /* eslint no-param-reassign: 0 */ - if (typeof data === 'string') { - enc = enc || 'utf8'; - data = Buffer.from(data, enc); - } + data = toBuffer(data, enc || 'utf8'); var block = this._block; var blockSize = this._blockSize;
package.json+2 −1 modified@@ -9,7 +9,8 @@ }, "dependencies": { "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" }, "devDependencies": { "@ljharb/eslint-config": "^21.1.1",
test/test.js+35 −4 modified@@ -6,6 +6,12 @@ var Buffer = require('safe-buffer').Buffer; var Sha1 = require('../').sha1; +var nodeSupportsUint16 = false; +try { + crypto.createHash('sha1').update(new Uint16Array()); + nodeSupportsUint16 = true; +} catch (err) {} + var inputs = [ ['', 'ascii'], ['abc', 'ascii'], @@ -15,8 +21,10 @@ var inputs = [ ['123456789abcdef123456789abcdef123456789abcdef123456789ab', 'ascii'], ['0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde', 'ascii'], ['0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'ascii'], - ['foobarbaz', 'ascii'] -]; + ['foobarbaz', 'ascii'], + [Buffer.from('buffer')], + nodeSupportsUint16 ? [new Uint16Array([1, 2, 3])] : null +].filter(Boolean); tape("hash is the same as node's crypto", function (t) { inputs.forEach(function (v) { @@ -35,7 +43,7 @@ tape('call update multiple times', function (t) { var sha1hash = crypto.createHash('sha1'); for (var i = 0; i < v[0].length; i = (i + 1) * 2) { - var s = v[0].substring(i, (i + 1) * 2); + var s = v[0].slice(i, (i + 1) * 2); hash.update(s, v[1]); sha1hash.update(s, v[1]); } @@ -74,7 +82,7 @@ tape('hex encoding', function (t) { var sha1hash = crypto.createHash('sha1'); for (var i = 0; i < v[0].length; i = (i + 1) * 2) { - var s = v[0].substring(i, (i + 1) * 2); + var s = v[0].slice(i, (i + 1) * 2); hash.update(Buffer.from(s, 'ascii').toString('hex'), 'hex'); sha1hash.update(Buffer.from(s, 'ascii').toString('hex'), 'hex'); } @@ -88,6 +96,29 @@ tape('hex encoding', function (t) { t.end(); }); +tape('throws on invalid input', function (t) { + var invalid = [ + {}, // non-arrayish + { length: 20 }, // undefined values + [NaN], // non-numbers + [[]], // non-numbers + [1, 1.5], // non-integers + [1, 256], // out of bounds + [-1, 0] // out of bounds + ]; + + invalid.forEach(function (input) { + var hash = new Sha1(); + + t['throws'](function () { + hash.update(input); + hash.digest('hex'); + }); + }); + + t.end(); +}); + tape('call digest for more than MAX_UINT32 bits of data', function (t) { var sha1hash = crypto.createHash('sha1'); var hash = new Sha1();
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
7- github.com/browserify/sha.js/pull/78ghsapatchWEB
- github.com/advisories/GHSA-95m3-7q98-8xr5ghsaADVISORY
- github.com/browserify/sha.js/security/advisories/GHSA-95m3-7q98-8xr5ghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2025-9288ghsaADVISORY
- github.com/browserify/sha.js/commit/f2a258e9f2d0fcd113bfbaa49706e1ac0d979ba5ghsaWEB
- lists.debian.org/debian-lts-announce/2025/09/msg00016.htmlghsaWEB
- www.cve.org/CVERecordghsarelatedWEB
News mentions
0No linked articles in our index yet.