From 0b359cd797d6ea5c96e7cdf23dc5f28906590764 Mon Sep 17 00:00:00 2001 From: Joel Biddle Date: Tue, 22 Aug 2023 19:45:35 +1000 Subject: [PATCH] Made breached pwd API comments clearer --- .../utilities/checks/PasswordCheck.ts | 5 ++--- .../checks/checkIsPasswordBreached.ts | 21 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/utilities/checks/PasswordCheck.ts b/frontend/src/components/utilities/checks/PasswordCheck.ts index cd75b53f9..92d891d97 100644 --- a/frontend/src/components/utilities/checks/PasswordCheck.ts +++ b/frontend/src/components/utilities/checks/PasswordCheck.ts @@ -14,12 +14,11 @@ interface PasswordCheckProps { const passwordCheck = ({ password, setPasswordErrorTooShort, + setPasswordErrorTooLong, setPasswordErrorNumber, setPasswordErrorLowerCase, - setPasswordErrorTooLong, errorCheck }: PasswordCheckProps) => { - if (!password || password.length < 14) { setPasswordErrorTooShort(true); errorCheck = true; @@ -27,7 +26,7 @@ const passwordCheck = ({ setPasswordErrorTooShort(false); } - if (password.length > 100) { + if (password.length > 100) { setPasswordErrorTooLong(true); errorCheck = true; } else { diff --git a/frontend/src/components/utilities/checks/checkIsPasswordBreached.ts b/frontend/src/components/utilities/checks/checkIsPasswordBreached.ts index e032ebd91..40a9330db 100644 --- a/frontend/src/components/utilities/checks/checkIsPasswordBreached.ts +++ b/frontend/src/components/utilities/checks/checkIsPasswordBreached.ts @@ -3,10 +3,10 @@ import crypto from "crypto"; // added types from @types/node export const checkIsPasswordBreached = async (password: string) => { // see API details here: https://haveibeenpwned.com/API/v3#SearchingPwnedPasswordsByRange - // in short, the pending password is hashed (SHA-1), fist 5 chars are sliced and compared against a ranged hash table + // in short, the pending password is hashed (SHA-1), the first 5 chars are sliced and compared against a ranged hash table // if there is a match, that password has been involved in a password breach and should not be accepted - // the database consists of ~700 mln breached passwords and is continuously being updated including with data from the FBI & the UK's NCA + // the database consists of ~700 mln breached passwords and is continuously updated // https://www.troyhunt.com/open-source-pwned-passwords-with-fbi-feed-and-225m-new-nca-passwords-is-now-live/ const dataBreachCheckAPIBaseURL = "https://api.pwnedpasswords.com/range/"; // added to CSP @@ -15,27 +15,26 @@ export const checkIsPasswordBreached = async (password: string) => { const textEncoder = new TextEncoder(); const encodedPwd = textEncoder.encode(password); const hash = crypto.createHash("sha1").update(encodedPwd).digest(); - - const hashedPwd = Array.from(new Uint8Array(hash)) + let hashedPwd = Array.from(new Uint8Array(hash)) .map((byte) => byte.toString(16).padStart(2, "0")) .join("") .toUpperCase(); + hashedPwd = hashedPwd.slice(0, 5); // ONLY the first five SHA-1 hash chars are sent over HTTPS (the whole string can be sent but that's not very secure due to SHA-1 flaws) - // Ensure that ONLY the first five SHA-1 hash chars are sent over HTTPS - const response = await axios.get(`${dataBreachCheckAPIBaseURL}${hashedPwd.slice(0, 5)}`); + const response = await axios.get(`${dataBreachCheckAPIBaseURL}${hashedPwd}`); const responseData = response.data.toUpperCase(); - const isBreachedPassword = responseData.includes(hashedPwd.slice(5, 40)); + const isBreachedPassword = responseData.includes(hashedPwd.slice(5, 40)); // compare against the API's ranged db's hash table - // Clear the hashed password from memory (good practice) + // Clear the hashed password from memory const zeroBuffer = new Uint8Array(encodedPwd.length); encodedPwd.set(zeroBuffer); - return isBreachedPassword; // boolean + return isBreachedPassword; // boolean: true === "password has been involved in a data breach" } catch (err: any) { if (axios.isAxiosError(err) && err.response && err.response.status === 429) { console.error("Received a 429 response from the Pwnd Passwords API"); - // Handle the 429 error here (not 100% sure what the rate limits are for the password API) - // an error here should not cause a fail of setting/resetting/changing the password + // Handle the 429 error here (not 100% sure what the rate limits are for the password API but looks like <10 calls/min) + // an error here should not cause the setting/resetting/changing password to fail (unless desired) } else { console.error(err); }