lpil / lpil/beecrypt

Verify panics if given an invalid bcrypt hash to check against

Open
#1 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Gleam
Stars
11
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Repro:

import beecrypt

pub fn main() {
  beecrypt.verify("something", "")
}
$ gleam run -m bcrypt_repro
   Compiled in 0.05s
    Running bcrypt_repro.main
runtime error: let assert

Pattern match failed, no pattern matched the value.

unmatched value:
  Error([98, 99, 114, 121, 112, 116, 32, 102, 97, 105, 108, 101, 100])

stacktrace:
  beecrypt.hash_with_salt src/beecrypt.gleam:24
  beecrypt.verify src/beecrypt.gleam:14

This panics because hash_with_salt assumes bcrypt:hashpw/2 will succeed:

https://github.com/lpil/beecrypt/blob/cb5ea82d8907156a5a66dbf87c9a78e309a3978a/src/beecrypt.gleam#L24

which it always should in the beecrypt.hash path but there's no guarantee in the beecrypt.verify path.

If you want to keep the API simple, you could move the let assert Ok into beecrypt.hash and handle the Error case in beecrypt.verify in the obvious way:

pub fn verify(password: String, hash: String) -> Bool {
  let salt = string.slice(hash, at_index: 0, length: 29)
  let hashed = case hash_with_salt(password, salt) {
    Ok(hash) -> hash
    Error(_) -> ""
  }
  crypto.secure_compare(<<hash:utf8>>, <<hashed:utf8>>)
}

If you want to be more complicated this could be made typesafe with something like:

pub opaque type BCryptHash {
    BCryptHash(String)
}

pub type Error {…}

pub fn hash_from_string(mb_hash: String) -> Result(BCryptHash, Error) { … }

but that seems like an unnecessary API break and I don't know of any prior art for something like that. Haskell's password package has a newtype for hashes but the constructor is exported so there's no guarantee a PasswordHash Bcrypt is a valid Bcrypt hash in general.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/beecrypt.gleam at verify on line 14 and hash_with_salt on line 24, then run the Gleam reproduction from the issue with an invalid hash. Ensure verification handles the bcrypt error without panicking, and confirm the invalid-hash case returns the intended boolean result.

Written by the indexing model from the issue text.

Assessment

Domain
security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.