Skip to content

crypto: coerce -0 keylen to +0 in pbkdf2 and scrypt#63531

Open
ljharb wants to merge 2 commits into
nodejs:mainfrom
ljharb:crypto-pbkdf2-negative-zero-keylen
Open

crypto: coerce -0 keylen to +0 in pbkdf2 and scrypt#63531
ljharb wants to merge 2 commits into
nodejs:mainfrom
ljharb:crypto-pbkdf2-negative-zero-keylen

Conversation

@ljharb
Copy link
Copy Markdown
Member

@ljharb ljharb commented May 24, 2026

validateInt32(keylen, 'keylen', 0) lets -0 through: typeof -0 is 'number', Number.isInteger(-0) is true, and -0 < 0 is false.
The value then reaches the PBKDF2Job binding, whose IsInt32() check fails (V8 boxes -0 as a HeapNumber rather than a tagged SMI) and aborts the process with SIGABRT.
Coerce keylen to +0 after validation so the binding sees a true Int32.

Reachable from any caller that forwards a JSON-parsed value, since JSON.parse('{"keylen":-0}').keylen preserves the sign.

(an alternative implementation would be to throw on -0 - this seemed friendlier, but I'm happy to do that instead, if folks prefer)

`validateInt32(keylen, 'keylen', 0)` lets `-0` through: `typeof -0` is
`'number'`, `Number.isInteger(-0)` is `true`, and `-0 < 0` is `false`.
The value then reaches the PBKDF2Job binding, whose `IsInt32()` check
fails (V8 boxes `-0` as a HeapNumber rather than a tagged SMI) and
aborts the process with SIGABRT.
Coerce `keylen` to `+0`
after validation so the binding sees a true Int32.

Reachable from any caller that forwards a JSON-parsed value,
since `JSON.parse('{"keylen":-0}').keylen` preserves the sign.

Signed-off-by: Jordan Harband <ljharb@gmail.com>
@ljharb ljharb added the crypto Issues and PRs related to the crypto subsystem. label May 24, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label May 24, 2026
@ljharb ljharb force-pushed the crypto-pbkdf2-negative-zero-keylen branch 2 times, most recently from e4b488e to 9700ffe Compare May 24, 2026 08:53
@panva
Copy link
Copy Markdown
Member

panva commented May 24, 2026

@ljharb can you throw in a fix for scrypt too?

@panva
Copy link
Copy Markdown
Member

panva commented May 24, 2026

Outside of pbkdf2 and scrypt there are also instances in cipher, diffiehellman, keygen, hash, random. I can tackle those separately in a followup if you want, or you can, up to you.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.31%. Comparing base (df09b2a) to head (c095afb).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63531      +/-   ##
==========================================
- Coverage   90.32%   90.31%   -0.02%     
==========================================
  Files         730      730              
  Lines      234152   234156       +4     
  Branches    43900    43912      +12     
==========================================
- Hits       211499   211467      -32     
- Misses      14374    14418      +44     
+ Partials     8279     8271       -8     
Files with missing lines Coverage Δ
lib/internal/crypto/pbkdf2.js 100.00% <100.00%> (+1.52%) ⬆️
lib/internal/crypto/scrypt.js 94.89% <100.00%> (+0.07%) ⬆️

... and 31 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.

@panva

This comment was marked as outdated.

Mirror of the prior pbkdf2 fix. `validateInt32(keylen, 'keylen', 0)`
lets `-0` through (since `-0 < 0` is `false`), and the ScryptJob
binding's `IsInt32()` check at `crypto_scrypt.cc` aborts the process
with SIGABRT because V8 boxes `-0` as a HeapNumber rather than a
tagged SMI. Coerce `keylen` to `+0` after validation.
@ljharb ljharb force-pushed the crypto-pbkdf2-negative-zero-keylen branch from 6a406f2 to c095afb Compare May 24, 2026 13:45
@panva panva added the commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. label May 24, 2026
@panva panva changed the title crypto: coerce -0 keylen to +0 in pbkdf2 crypto: coerce -0 keylen to +0 in pbkdf2 and scrypt May 24, 2026
@panva panva added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels May 24, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label May 24, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

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

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. 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.

5 participants