Skip to content

crypto: runtime-deprecate calling Hmac.digest() more than once (DEP0206)#63162

Open
Anshikakalpana wants to merge 1 commit into
nodejs:mainfrom
Anshikakalpana:hmac-runtime-dep-0206
Open

crypto: runtime-deprecate calling Hmac.digest() more than once (DEP0206)#63162
Anshikakalpana wants to merge 1 commit into
nodejs:mainfrom
Anshikakalpana:hmac-runtime-dep-0206

Conversation

@Anshikakalpana
Copy link
Copy Markdown
Contributor

Refs: #62838
Refs: #63121

Situation

Calling digest() on an already-finalized Hmac instance currently returns an empty buffer silently instead of throwing an error. This is inconsistent with Hash behavior which throws ERR_CRYPTO_HASH_FINALIZED and is a potential security footgun.

Change

Add a runtime deprecation warning (DEP0206) when digest() is called more than once on an Hmac instance. The existing behavior (returning an empty buffer) is preserved during the deprecation cycle to avoid breaking changes. docs-only deprecation was introduced in #63121.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto
  • @nodejs/userland-migrations

@nodejs-github-bot nodejs-github-bot added crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. labels May 6, 2026
@Anshikakalpana Anshikakalpana force-pushed the hmac-runtime-dep-0206 branch 3 times, most recently from c26a78a to 096abf3 Compare May 6, 2026 20:11
Signed-off-by: anshikakalpana <anshikajain196872@gmail.com>
@Anshikakalpana Anshikakalpana force-pushed the hmac-runtime-dep-0206 branch from 096abf3 to b7bc8a8 Compare May 6, 2026 21:18
@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.04%. Comparing base (3c2d2e3) to head (b7bc8a8).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63162      +/-   ##
==========================================
- Coverage   90.04%   90.04%   -0.01%     
==========================================
  Files         713      713              
  Lines      224484   224505      +21     
  Branches    42430    42426       -4     
==========================================
+ Hits       202134   202146      +12     
- Misses      14156    14161       +5     
- Partials     8194     8198       +4     
Files with missing lines Coverage Δ
lib/internal/crypto/hash.js 99.03% <100.00%> (+0.02%) ⬆️

... and 26 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Anshikakalpana
Copy link
Copy Markdown
Contributor Author

The slim tarball CI checks are failing with an unexpected DEP0206 warning in test-crypto-hmac.js. could someone help me understand how to fix this?

Copy link
Copy Markdown

@soulee-dev soulee-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root cause: common.expectWarning keys handlers by warning name, so the inline expectWarning at the bottom of test-crypto-hmac.js (added by #52071 for DEP0181) overwrites the new top-of-file registration this PR adds.
By the time both warnings emit asynchronously on process.nextTick, only the DEP0181 handler is active, DEP0206 then hits an empty expected list and triggers Unexpected extra warning received in CI.

The suggestions move both expectations into the top expectWarning and drop the duplicate block. Line 18 already covers DEP0181.

Verified on a fork I pushed both changes to my fork and ran the full GitHub Actions matrix at https://github.com/soulee-dev/node/pull/1:`parallel/test-crypto-hmac`, parallel/test-crypto-dep0206, and all the previously-failing workflows (test-linux, test-macOS, test-tarball, shared-libraries) pass green.

If you commit the first suggestion via GitHub's "Commit suggestion" button,
GitHub will automatically add me as Co-Authored-By on that commit. For the block-deletion comment, would you mind adding Co-Authored-By: Soul Lee <alus20x@gmail.com> manually when you amend? Thanks!

Comment on lines +10 to +14
common.expectWarning({
DeprecationWarning: {
DEP0206: 'Calling digest() on an already-finalized Hmac instance is deprecated.',
},
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
common.expectWarning({
DeprecationWarning: {
DEP0206: 'Calling digest() on an already-finalized Hmac instance is deprecated.',
},
});
common.expectWarning({
DeprecationWarning: {
DEP0181: 'crypto.Hmac constructor is deprecated.',
DEP0206: 'Calling digest() on an already-finalized Hmac instance is
deprecated.',
},
});

The existing inline expectWarning block at the bottom of this file (lines
471–478) registers a separate handler for DeprecationWarning, which
overwrites this one because expectWarning is keyed by warning name. Adding
DEP0181 here lets us drop the bottom block — see the review summary for the
full rationale and the additional deletion.

Comment on lines 471 to 478
crypto.Hmac('sha256', 'Node');
common.expectWarning({
DeprecationWarning: [
['crypto.Hmac constructor is deprecated.',
'DEP0181'],
]
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also delete this block:

  -{
  -  crypto.Hmac('sha256', 'Node');
  -  common.expectWarning({
  -    DeprecationWarning: [
  -      ['crypto.Hmac constructor is deprecated.',
  -       'DEP0181'],
  -    ]
  -  });
  -}

DEP0181 now registered at the top of the file (suggestion above),
this inline registration is the source of the conflict. Line 18's
crypto.Hmac('sha256', 'Node') already exercises the
constructor-without-new path, so removing this block doesn't lose coverage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the detailed root cause analysis and for verifying on your fork! Will make both changes shortly and add you as co-author.

Copy link
Copy Markdown
Member

@AugustinMauroy AugustinMauroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT !

Comment thread doc/api/deprecations.md
throwing an error. This behavior is inconsistent with `hash.digest()` and
may lead to subtle bugs. Calling `hmac.digest()` on a finalized `Hmac` instance
will throw an error in a future version.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To help user that face this deprecation, we should have an code example of what happened

const crypto = require('crypto');

const hmac = crypto.createHmac('sha256', 'secret');

hmac.update('hello');

console.log(hmac.digest('hex')); // works

console.log(hmac.digest('hex')); // ❌ currently returns empty string/buffer

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the suggestion! I'll add the code example to the deprecations doc shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants