cloudflare / cloudflare/workerd
🐛 Bug Report Runtime APIs node:crypto: Hmac.prototype.digest silently returns empty Buffer on second call instead of throwing ERR_CRYPTO_HASH_FINALIZED
- Dominant language
- C++
- Stars
- 8.7k
- Forks
- 739
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 174
Description
### Description
Calling `hmac.digest()` a second time silently returns an empty `Buffer` (or `''`)
instead of throwing `ERR_CRYPTO_HASH_FINALIZED`, diverging from both Node.js behavior
and the existing `Hash.prototype.digest` implementation in the same file.
### Reproduction
```js
import { createHmac } from 'node:crypto';
const hmac = createHmac('sha256', 'secret');
hmac.update('data');
const first = hmac.digest('hex'); // correct HMAC
const second = hmac.digest('hex'); // should throw, but returns '' in workerd
console.log(second); // '' — silent wrong result
```
### Expected behavior (Node.js v22)
The second `hmac.digest()` call throws:
Error [ERR_CRYPTO_HASH_FINALIZED]: Digest already called
### Actual behavior (workerd)
Returns `''` (empty string) or `Buffer.from('')` silently, producing a wrong result
without any indication of the error.
### Root cause
In `src/node/internal/crypto_hash.ts`, `Hash.prototype.digest` correctly throws
`ERR_CRYPTO_HASH_FINALIZED` on a second call, but `Hmac.prototype.digest` has:
```ts
if (state[kFinalized]) {
return !outputEncoding || outputEncoding === 'buffer'
? Buffer.from('') // ← silently wrong
: '';
}
```
**Fix:** Replace the early return with `throw new ERR_CRYPTO_HASH_FINALIZED()`.
### Impact
Silent data corruption callers get an empty HMAC value thinking it's correct.
Contributor guide
Research direction
Start in src/node/internal/crypto_hash.ts and compare Hmac.prototype.digest with the existing Hash.prototype.digest finalized-state handling. Verify the behavior with the reproduction: the first digest returns the HMAC, while a second call throws ERR_CRYPTO_HASH_FINALIZED rather than returning an empty string or Buffer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- api, security
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100