Skip to content

fix(isHashMatch): check that hash starts with $ #3698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/node/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,13 @@ export const hash = async (password: string): Promise<string> => {
* Used to verify if the password matches the hash
*/
export const isHashMatch = async (password: string, hash: string) => {
if (password === "" || hash === "") {
if (password === "" || hash === "" || !hash.startsWith("$")) {
return false
}
try {
return await argon2.verify(hash, password)
} catch (error) {
logger.error(error)
return false
throw new Error(error)
}
}

Expand Down
11 changes: 11 additions & 0 deletions test/unit/node/util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ describe("isHashMatch", () => {
const actual = await util.isHashMatch(password, _hash)
expect(actual).toBe(false)
})
it("should return false and not throw an error if the hash doesn't start with a $", async () => {
const password = "hellowpasssword"
const _hash = "n2i$v=19$m=4096,t=3,p=1$EAoczTxVki21JDfIZpTUxg$rkXgyrW4RDGoDYrxBFD4H2DlSMEhP4h+Api1hXnGnFY"
expect(async () => await util.isHashMatch(password, _hash)).not.toThrow()
expect(await util.isHashMatch(password, _hash)).toBe(false)
})
it("should reject the promise and throw if error", async () => {
const password = "hellowpasssword"
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious - what does it mean when the hash begins with a $? Is it used as a signifier to designate that the hash is Argon2? I had thought that the other test case was an Argon2 hash, too, so this is a little confusing for me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just curious - what does it mean when the hash begins with a $? Is it used as a signifier to designate that the hash is Argon2?

AFAIK, I believe that's exactly why.

had thought that the other test case was an Argon2 hash, too, so this is a little confusing for me

If you point out which test case you're referring to, happening to clear up any confusion!

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry I meant that this:

    const _hash = "n2i$v=19$m=4096,t=3,p=1$EAoczTxVki21JDfIZpTUxg$rkXgyrW4RDGoDYrxBFD4H2DlSMEhP4h+Api1hXnGnFY"

Looks like a valid hash to me, but I guess it's not? What is this hash?

I guess it makes sense that it has to start with $ since a valid hash looks like const _hash = "$argon2i$v=19$m=4096,t=3,p=1$EAoczTxVki21JDfIZpTUxg$rkXgyrW4RDGoDYrxBFD4H2DlSMEhP4h+Api1hXnGnFY"?

Should we look for "$argon2i$" instead of just the $?

const _hash = "$ar2i"
expect(async () => await util.isHashMatch(password, _hash)).rejects.toThrow()
})
})

describe("hashLegacy", () => {
Expand Down