Skip to content

fix: validate that rounds is an integer in genSalt and hash - #177

Open
RajatX24 wants to merge 1 commit into
dcodeIO:mainfrom
RajatX24:fix/non-integer-rounds-173
Open

RajatX24 wants to merge 1 commit into
dcodeIO:mainfrom
RajatX24:fix/non-integer-rounds-173

Conversation

@RajatX24

@RajatX24 RajatX24 commented Nov 10, 2026 •

Copy link
Copy Markdown

Fixes #173

Problem

rounds is bcrypt's cost factor (how many hashing iterations run). Valid values are integers from 4 to 31 (out-of-range integers are clamped to that range). genSaltSync never checked this, so a non-integer like 10.5 produced a broken salt, and the error only appeared later in hashSync.

import bcrypt from "bcryptjs";

const salt = bcrypt.genSaltSync(10.5); // "$2b$10.5$..." (invalid)
bcrypt.hashSync("my-password", salt);  // Error: Missing salt rounds

Fix

  • genSaltSync now throws Illegal arguments: rounds must be an integer for non-integers (10.5, Infinity). genSalt inherits this (rejects or passes the error to the callback).
  • hash(password, <number>) now forwards genSalt errors to the callback or promise. Before, they were dropped and users saw a misleading Invalid string / salt: Not a string.
  • JSDoc and types.d.ts updated with @throws / @rejects.

After the fix:

bcrypt.genSaltSync(10.5); // Error: Illegal arguments: rounds must be an integer

Behavior change: genSaltSync(Infinity) used to be clamped to 31. It now throws, since Infinity is not an integer.

Tests

Added to tests/index.js, covering genSaltSync, genSalt (promise and callback), hashSync and hash:

  • 10.5 and Infinity are rejected with the new error.
  • Valid costs (4, 10, 31) still embed the right cost in the salt.

npm test, npm run lint and npm run build pass locally.

Will add a Loom video covering the changes


Made with Operate, reviewed and tested locally.
Investigation: https://operatex.dev/open-source/github/dcodeIO/bcrypt.js/issues/173

@RajatX24
RajatX24 force-pushed the fix/non-integer-rounds-173 branch from 163ab30 to 7c3c664 Compare November 12, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

genSaltSync accepts a non-integer cost and returns a salt that hashSync rejects

1 participant