Skip to content

Fix out-of-bounds read in ValidateSalt for short salts#1230

Open
Hashim1999164 wants to merge 1 commit into
kelektiv:masterfrom
Hashim1999164:fix/validate-salt-oob-read
Open

Fix out-of-bounds read in ValidateSalt for short salts#1230
Hashim1999164 wants to merge 1 commit into
kelektiv:masterfrom
Hashim1999164:fix/validate-salt-oob-read

Conversation

@Hashim1999164

Copy link
Copy Markdown

Summary

ValidateSalt in src/bcrypt_node.cc only checked the leading $ and then read fixed offsets (salt[1], salt[2]) while advancing the pointer. A truncated $-prefixed salt such as "$", "$2b", or "$2b$" therefore read one or two bytes past the terminating NUL, an out-of-bounds read (CWE-125) reachable from compare/compareSync/encrypt/encryptSync.

This adds bounds checks so short salts are rejected before the pointer is advanced:

  • return early if the version byte is \0 (handles "$")
  • require the $ separator after the version (handles "$2b", "$2b$")
  • guard the cost digits against an early \0 before reading the trailing separator

Valid salts are unaffected.

Fixes #1228.

Verification

  • npx node-gyp rebuild && npx jest -> all 76 tests pass, including a new hash_short_salt_prefix regression test in test/sync.test.js that feeds truncated salts to hashSync/compareSync.
  • Extracted the old and new ValidateSalt into a standalone harness built with -fsanitize=address, using exact-sized heap buffers (so no small-string-optimization slack hides the read):
    • Original: heap-buffer-overflow (READ of size 1) for "$", "$2b", and "$2b$" at the salt[1] / salt[2] reads.
    • Fixed: all return false with no ASAN error; a valid $2a$10$... salt still validates.

Test plan

  • npx node-gyp rebuild
  • npx jest (76 passing)
  • ASAN before/after comparison on truncated salts

Made with Cursor

ValidateSalt walked the salt pointer and read fixed offsets (salt[1],
salt[2]) after only checking the leading '$', so a truncated salt such
as "$", "$2b" or "$2b$" caused reads past the terminating NUL byte.

Reject these short salts before advancing the pointer: bail out when the
version byte is NUL, require the '$' separator after the version, and
guard the cost digits against an early NUL. Valid salts are unaffected.

Fixes kelektiv#1228.
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.

Possible out-of-bounds read in ValidateSalt for a short $-prefixed salt/hash

1 participant