From 464e93a405d831d6496d56956673068f3282436e Mon Sep 17 00:00:00 2001 From: Abhishek Balam Date: Tue, 1 Jun 2021 21:32:32 +0530 Subject: [PATCH] fix: Allow only use of Fernet generated key for using custom encryption_key (#13399) * fix: only allow keys generated by fernet in encrypt()/decrypt() * fix: sider and semgrep fixes --- frappe/tests/test_password.py | 4 ++-- frappe/utils/password.py | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/frappe/tests/test_password.py b/frappe/tests/test_password.py index 9b68f3aace3..6bc4bc77290 100644 --- a/frappe/tests/test_password.py +++ b/frappe/tests/test_password.py @@ -4,7 +4,7 @@ import frappe import unittest from frappe.utils.password import update_password, check_password, passlibctx, encrypt, decrypt - +from cryptography.fernet import Fernet class TestPassword(unittest.TestCase): def setUp(self): frappe.delete_doc('Email Account', 'Test Email Account Password') @@ -107,7 +107,7 @@ def test_password_unset(self): def test_custom_encryption_key(self): text = 'Frappe Framework' - custom_encryption_key = 'DFTBA' + custom_encryption_key = Fernet.generate_key().decode() encrypted_text = encrypt(text, encryption_key=custom_encryption_key) decrypted_text = decrypt(encrypted_text, encryption_key=custom_encryption_key) diff --git a/frappe/utils/password.py b/frappe/utils/password.py index d97c7885687..34719eb384d 100644 --- a/frappe/utils/password.py +++ b/frappe/utils/password.py @@ -61,7 +61,7 @@ def set_encrypted_password(doctype, name, pwd, fieldname='password'): except frappe.db.DataError as e: if ((frappe.db.db_type == 'mariadb' and e.args[0] == DATA_TOO_LONG) or (frappe.db.db_type == 'postgres' and e.pgcode == STRING_DATA_RIGHT_TRUNCATION)): - frappe.throw("Most probably your password is too long.", exc=e) + frappe.throw(_("Most probably your password is too long.", exc=e)) raise e @@ -158,12 +158,21 @@ def create_auth_table(): def encrypt(txt, encryption_key=None): - cipher_suite = Fernet(encode(encryption_key or get_encryption_key())) + # Only use Fernet.generate_key().decode() to enter encyption_key value + + try: + cipher_suite = Fernet(encode(encryption_key or get_encryption_key())) + except Exception: + # encryption_key is not in 32 url-safe base64-encoded format + frappe.throw(_('Encryption key is in invalid format!')) + cipher_text = cstr(cipher_suite.encrypt(encode(txt))) return cipher_text def decrypt(txt, encryption_key=None): + # Only use encryption_key value generated with Fernet.generate_key().decode() + try: cipher_suite = Fernet(encode(encryption_key or get_encryption_key())) plain_text = cstr(cipher_suite.decrypt(encode(txt)))