Skip to main content

Overview

This vulnerability occurs when an application uses cryptographic algorithms that are known to be weak, broken, or deprecated. This includes using outdated hashing algorithms like MD5 or SHA1 for password storage, using weak encryption ciphers like DES, or employing cryptographic modes that are susceptible to attacks (like ECB mode for block ciphers).

Business Impact

Using broken cryptography provides a false sense of security. 🛡️ Attackers can often break this weak protection easily, leading to the compromise of sensitive data like passwords, PII, or financial information. If password hashes are cracked, attackers gain access to user accounts. If encryption is broken, all encrypted data is exposed.

Reference Details

CWE ID: CWE-327 OWASP Top 10 (2021): A02:2021 - Cryptographic Failures Severity: High

Framework-Specific Analysis and Remediation

Modern frameworks generally default to strong algorithms (e.g., bcrypt/Argon2 for passwords, AES-GCM for encryption). This vulnerability arises when developers:
  1. Explicitly choose a weak algorithm (often for legacy compatibility or misunderstanding).
  2. Use outdated libraries or configurations.
  3. Implement crypto manually instead of using framework defaults.
The fix is to always use current, industry-standard algorithms recommended by NIST or other reputable bodies and rely on the framework’s built-in secure defaults.
  • Python
  • Java
  • .NET(C#)
  • PHP
  • Node.js
  • Ruby

Framework Context

Django defaults to PBKDF2_SHA256 for passwords, which is acceptable but bcrypt or Argon2 are stronger. For encryption, developers might use the older hashlib for passwords or weak pycryptodome configurations.

Vulnerable Scenario 1: Using MD5 for Passwords

A legacy system or custom user model uses MD5 directly.
# models.py (Custom User Model)
import hashlib

def check_password(self, raw_password):
    # DANGEROUS: MD5 is broken and easily cracked.
    return hashlib.md5(raw_password.encode()).hexdigest() == self.password_hash

Vulnerable Scenario 2: Weak Encryption Cipher

Using pycryptodome with DES or ECB mode.
# utils/encryption.py
from Crypto.Cipher import DES, AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad # Added import

def encrypt_data_des(key, data):
    # DANGEROUS: DES has a small key size (56-bit) and is broken.
    cipher = DES.new(key, DES.MODE_ECB) # ECB mode is also insecure
    return cipher.encrypt(pad(data.encode(), DES.block_size)) # Added encode() and block_size

def encrypt_data_aes_ecb(key, data):
    # DANGEROUS: AES itself is strong, but ECB mode leaks patterns.
    cipher = AES.new(key, AES.MODE_ECB)
    return cipher.encrypt(pad(data.encode(), AES.block_size)) # Added encode() and block_size

Mitigation and Best Practices

Use Django’s default password hashing (django.contrib.auth.hashers). If you need stronger hashing, configure PASSWORD_HASHERS to prioritize bcrypt or Argon2. For encryption, use AES with GCM mode (provides integrity) or CBC mode with a random IV and MAC.

Secure Code Example

# settings.py (Secure Password Hashers)
PASSWORD_HASHERS = [
    'django.contrib.auth.hashers.Argon2PasswordHasher', # Preferred
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', # Legacy support only
]

# utils/encryption.py (Secure AES-GCM)
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

def encrypt_data_aes_gcm(key, data):
    # SECURE: AES-GCM provides confidentiality and integrity.
    nonce = get_random_bytes(12) # GCM recommended nonce size
    cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
    ciphertext, tag = cipher.encrypt_and_digest(data.encode())
    # Store or transmit nonce + ciphertext + tag
    return nonce + ciphertext + tag

Testing Strategy

Check the password field in your user database. Hashes should start with prefixes like argon2$, bcrypt$, or pbkdf2_sha256$, not just raw hex. For encryption, write unit tests ensuring the correct algorithm (AES) and mode (GCM/CBC) are used.