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
This commit is contained in:
Abhishek Balam 2021-06-01 21:32:32 +05:30 committed by GitHub
parent 2da53b652b
commit 464e93a405
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 4 deletions

View file

@ -4,7 +4,7 @@ from __future__ import unicode_literals
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 @@ class TestPassword(unittest.TestCase):
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)

View file

@ -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)))