Created on 2021-11-24 22:36 by rouilj, last changed 2022-05-12 02:51 by rouilj.
|msg7371||Author: [hidden] (rouilj)||Date: 2021-11-24 22:36|
Somebody asked if Roundup supported Have I been Powned (https://haveibeenpwned.com/) using the password API: https://haveibeenpwned.com/API/v3 It doesn't but along the lines of https://wiki.roundup-tracker.org/TestPasswordComplexity a similar mechanism can use: https://pypi.org/project/pyhibp/ to get a password check. Also adding support for specifying an API key (https://haveibeenpwned.com/API/Key) in: detectors/config.ini for the tracker allows use of checks for the email address(es) of the user that can be done in a detector.
|msg7425||Author: [hidden] (rouilj)||Date: 2021-12-21 01:06|
Adding this function allows checking the entered password for exposure on have I been powned. import hashlib import requests from roundup.exceptions import Reject def check_pw_hibp(password, mode="change"): # encode to unicode string and return a hex encoded sha1 hash pwhash = hashlib.sha1(password.encode()).hexdigest() # search hibp using the first 5 hash characters try: rqst = requests.get('https://api.pwnedpasswords.com/range/' + pwhash[:5], timeout=2.5) # timeout 2.5 seconds except requests.exceptions.Timeout: return False # don't let API failure stop login or change # turn string like FA31ED547EE63D61B812DABE2F37D2AAFE2:2\r\n<another hash> # into list element of FA31ED547EE63D61B812DABE2F37D2AAFE2 res_hash_list = [ x.split(':') for x in rqst.text.split('\r\n') ] # hibp returns hash residual after removing first 5 requested chars # so search for it. if pwhash.upper()[5:] in res_hash_list: if mode == 'change': # reject change of password to the password value raise Reject("Password has been exposed on have i been powned. ") elif mode == "login": # Evaluates to true - have been found on hibp. Allow # the user to login (and change password) but provide an error message. return "Warning password has been exposed on have i been powned. Change password" return False # false == not found in hibp Using the technique in: https://wiki.roundup-tracker.org/TestPasswordComplexity and calling this with mode="change" allows you to check it when it gets changed. You can put this in the login flow using the technique in: https://wiki.roundup-tracker.org/LoginWithEmail so the password is checked for exposure on every login. Use code like: r = check_pw_hibp(self.form['__login_password'].value) if r: self.client.add_error_message(r) in the login action wrapper. Probably checking in both places is a good idea. One makes sure the user isn't starting off with an exposed password and the other verifies that it is still unexposed. I put this on the wiki as well. https://wiki.roundup-tracker.org/CheckForExposedPasswordHIBP
|msg7515||Author: [hidden] (rouilj)||Date: 2022-05-12 02:51|
Since this is documented on the wiki, I consider it done.
|2022-05-12 02:51:25||rouilj||set||priority: normal|
messages: + msg7515
status: new -> closed
|2021-12-21 01:06:58||rouilj||set||messages: + msg7425|