Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions vulnerable_weak_crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ def verify_password(input_password, stored_hash):
return input_hash == stored_hash

def encrypt_sensitive_data(data):
key = b'weakkey1'
cipher = DES.new(key, DES.MODE_ECB)
return cipher.encrypt(data.encode().ljust(8))
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
key = get_random_bytes(32)
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(data.encode())
return cipher.nonce + tag + ciphertext

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random encryption key generated but never returned

High Severity

encrypt_sensitive_data generates a random key via get_random_bytes(32) but only returns the nonce, tag, and ciphertext — the key is discarded when the function returns. This means the encrypted data can never be decrypted. The previous (insecure) implementation used a hardcoded key, which at least allowed decryption. The fix swapped a security problem for a complete loss of functionality.

Fix in Cursor Fix in Web

Comment on lines +46 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Encryption key is generated randomly but never returned, making decryption impossible

The new encrypt_sensitive_data function generates a random AES-256 key via get_random_bytes(32) on every call, but the key is never returned or stored. The function only returns cipher.nonce + tag + ciphertext. Without the key, there is no way to decrypt the data, rendering the encryption useless — the data is effectively destroyed. The old code used a hardcoded key (b'weakkey1'), which was insecure but at least allowed decryption. The function should either return the key alongside the ciphertext (e.g., as a tuple) or accept the key as a parameter.

Suggested change
key = get_random_bytes(32)
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(data.encode())
return cipher.nonce + tag + ciphertext
key = get_random_bytes(32)
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(data.encode())
return key, cipher.nonce + tag + ciphertext
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


def generate_otp():
return str(random.randrange(100000, 999999))
Loading