No need to have avoid timing side-channel attack in user_add. We're just going to tell you if the user already exists anyway.

This commit is contained in:
James Valleroy 2013-11-04 02:37:12 +00:00 committed by Nick Daly
parent 96edae33ed
commit 2f7b56e6a9
2 changed files with 18 additions and 20 deletions

View File

@ -8,7 +8,7 @@ Here is an overview of how user passwords are currently being stored in Plinth.
1. We check if the username or password is empty. If so, return an error message.
2. Use bcrypt (from passlib) to encrypt the password and generate a random salt. This step is performed regardless of whether the user already exists.
2. Use bcrypt (from passlib) to encrypt the password and generate a random salt.
3. If the password length is over 4096, bcrypt raises an exception. We catch this exception and return an error message.

View File

@ -23,29 +23,27 @@ def add_user(username, passphrase, name='', email='', expert=False):
if not username: error = "Must specify a username!"
if not passphrase: error = "Must specify a passphrase!"
if error is None:
# hash the password whether the user exists, to foil timing
# side-channel attacks
try:
pass_hash = bcrypt.encrypt(passphrase)
except PasswordSizeError:
error = "Password is too long."
if error is None:
if username in map(lambda x: x[0], cfg.users.get_all()):
error = "User already exists!"
else:
di = {
'username':username,
'name':name,
'email':email,
'expert':'on' if expert else 'off',
'groups':['expert'] if expert else [],
'passphrase':pass_hash,
'salt':pass_hash[7:29], # for bcrypt
}
new_user = User(di)
cfg.users.set(username,new_user)
try:
pass_hash = bcrypt.encrypt(passphrase)
except PasswordSizeError:
error = "Password is too long."
if error is None:
di = {
'username':username,
'name':name,
'email':email,
'expert':'on' if expert else 'off',
'groups':['expert'] if expert else [],
'passphrase':pass_hash,
'salt':pass_hash[7:29], # for bcrypt
}
new_user = User(di)
cfg.users.set(username,new_user)
if error:
cfg.log(error)