From 72a3fd6f02cd1d15f23c8d2829998912a9587bd1 Mon Sep 17 00:00:00 2001 From: Leo Developer Date: Tue, 18 Jun 2024 22:21:20 +0200 Subject: [PATCH] veb.auth: use constant time comparision in compare_password_with_hash (#21693) --- vlib/veb/auth/README.md | 10 ++++++++++ vlib/veb/auth/auth.v | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/vlib/veb/auth/README.md b/vlib/veb/auth/README.md index fd5ece0dc4..b36bcd4e00 100644 --- a/vlib/veb/auth/README.md +++ b/vlib/veb/auth/README.md @@ -89,3 +89,13 @@ pub fn (mut app App) find_user_by_name(name string) ?User { return User{} } ``` + +## Security considerations + +`hash_password_with_salt` and its related functions use `sha256` for hashing with a single +iteration. This is not secure for production use, and you should use a more secure hashing +algorithm and multiple iterations. + +See also: +- [OWASP Password Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) + diff --git a/vlib/veb/auth/auth.v b/vlib/veb/auth/auth.v index 69e70b2e29..57baeaea13 100644 --- a/vlib/veb/auth/auth.v +++ b/vlib/veb/auth/auth.v @@ -5,6 +5,7 @@ module auth import rand import crypto.rand as crypto_rand +import crypto.hmac import crypto.sha256 const max_safe_unsigned_integer = u32(4_294_967_295) @@ -84,5 +85,9 @@ pub fn hash_password_with_salt(plain_text_password string, salt string) string { } pub fn compare_password_with_hash(plain_text_password string, salt string, hashed string) bool { - return hash_password_with_salt(plain_text_password, salt) == hashed + digest := hash_password_with_salt(plain_text_password, salt) + // constant time comparison + // I know this is operating on the hex-encoded strings, but it's still constant time + // and better than not doing it at all + return hmac.equal(digest.bytes(), hashed.bytes()) }