aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-03-08 11:18:35 +0300
committerFrederick Muriuki Muriithi2023-03-08 11:18:35 +0300
commit5a8cc0d7fc241494580cd4a060690eaf09ff46d7 (patch)
treeeb9a9fa88027f28d2ec1421f0080e4260ecfe12d
parent8621b737b01be5a6f238725c65771dea1410f0bb (diff)
downloadgenenetwork3-5a8cc0d7fc241494580cd4a060690eaf09ff46d7.tar.gz
Replace Bcrypt with Argon2 for better security.
Bcrypt is now somewhat vulnerable to offline cracking, so we move our password hashing over to Argon2.
-rw-r--r--README.md12
-rw-r--r--gn3/auth/authentication/users.py12
-rw-r--r--main.py4
-rw-r--r--mypy.ini6
4 files changed, 23 insertions, 11 deletions
diff --git a/README.md b/README.md
index f328e87..1026ac4 100644
--- a/README.md
+++ b/README.md
@@ -194,17 +194,17 @@ following environment variable(s):
To run tests:
```bash
-$ export AUTHLIB_INSECURE_TRANSPORT=true
-$ export OAUTH2_ACCESS_TOKEN_GENERATOR="tests.unit.auth.test_token.gen_token"
-$ pytest
+export AUTHLIB_INSECURE_TRANSPORT=true
+export OAUTH2_ACCESS_TOKEN_GENERATOR="tests.unit.auth.test_token.gen_token"
+pytest
```
To specify unit-tests:
```bash
-$ export AUTHLIB_INSECURE_TRANSPORT=true
-$ export OAUTH2_ACCESS_TOKEN_GENERATOR="tests.unit.auth.test_token.gen_token"
-$ pytest -k unit_test
+export AUTHLIB_INSECURE_TRANSPORT=true
+export OAUTH2_ACCESS_TOKEN_GENERATOR="tests.unit.auth.test_token.gen_token"
+pytest -k unit_test
```
Running pylint:
diff --git a/gn3/auth/authentication/users.py b/gn3/auth/authentication/users.py
index 54838a3..5ee148f 100644
--- a/gn3/auth/authentication/users.py
+++ b/gn3/auth/authentication/users.py
@@ -2,7 +2,8 @@
from uuid import UUID, uuid4
from typing import Any, Tuple, NamedTuple
-import bcrypt
+from argon2 import PasswordHasher
+from argon2.exceptions import VerifyMismatchError
from gn3.auth import db
from gn3.auth.authorisation.errors import NotFoundError
@@ -60,7 +61,11 @@ def valid_login(conn: db.DbConnection, user: User, password: str) -> bool:
if row is None:
return False
- return bcrypt.checkpw(password.encode("utf-8"), row["password"])
+ hasher = PasswordHasher() # TODO: Maybe tune the parameters here...
+ try:
+ return hasher.verify(row["password"], password)
+ except VerifyMismatchError as _vme:
+ return False
def save_user(cursor: db.DbCursor, email: str, name: str) -> User:
"""
@@ -79,7 +84,8 @@ def save_user(cursor: db.DbCursor, email: str, name: str) -> User:
def set_user_password(
cursor: db.DbCursor, user: User, password: str) -> Tuple[User, bytes]:
"""Set the given user's password in the database."""
- hashed_password = bcrypt.hashpw(password.encode("utf8"), bcrypt.gensalt())
+ hasher = PasswordHasher() # TODO: Maybe tune the parameters here...
+ hashed_password = hasher.hash(password)
cursor.execute(
("INSERT INTO user_credentials VALUES (:user_id, :hash) "
"ON CONFLICT (user_id) DO UPDATE SET password=:hash"),
diff --git a/main.py b/main.py
index 6dadac2..49e5d55 100644
--- a/main.py
+++ b/main.py
@@ -7,7 +7,7 @@ from datetime import datetime
import click
-import bcrypt
+from argon2 import PasswordHasher
from yoyo import get_backend, read_migrations
from gn3 import migrations
@@ -37,7 +37,7 @@ def __init_dev_users__():
"password": "testpasswd"},)
def __hash_passwd__(passwd):
- return bcrypt.hashpw(passwd.encode("utf8"), bcrypt.gensalt())
+ return PasswordHasher().hash(passwd)
with db.connection(app.config["AUTH_DB"]) as conn, db.cursor(conn) as cursor:
cursor.executemany(dev_users_query, dev_users)
diff --git a/mypy.ini b/mypy.ini
index 52ea938..a4ae96e 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -63,3 +63,9 @@ ignore_missing_imports = True
[mypy-email_validator]
ignore_missing_imports = True
+
+[mypy-argon2]
+ignore_missing_imports = True
+
+[mypy-argon2.*]
+ignore_missing_imports = True \ No newline at end of file