Skip Content

A04: Cryptographic Failures

What is a cryptographic failure?

Cryptographic Failures happen when an application mishandles secrets, encryption, hashing, or key management in a way that exposes data.

Laravel 12 documents application key usage and supports previous keys via APP_PREVIOUS_KEYS; it also provides encryption services and secure hashing with Bcrypt and Argon2.

Typical Laravel failure

  • Storing secrets or tokens in plain text.
  • Encrypting inconsistently.
  • Weak key management.
  • Confusing hashing with encryption.
  • Rotating keys badly.

Impact

  • Credential disclosure (passwords, API tokens) and account takeover.
  • Sensitive data exposure (PII, financial data) if encryption is missing or broken.
  • Permanent loss of access to encrypted data after bad key rotation.
  • Incident amplification when secrets appear in logs.

Laravel 12 remediation

  • Use Hash for passwords (one-way), never encryption.
  • Use Crypt only for decryptable sensitive values.
  • Protect and rotate APP_KEY correctly.
  • Use APP_PREVIOUS_KEYS during rotation to avoid breaking old encrypted values.
  • Never log secrets, OTP seeds, reset tokens, API tokens, or raw personal data.

Concrete fix

Rotate APP_KEY safely using APP_PREVIOUS_KEYS so old encrypted values can still be decrypted:

# .env (example)
 
# New key
APP_KEY=base64:NEW_KEY_HERE
 
# One or more old keys, comma-separated
APP_PREVIOUS_KEYS=base64:OLD_KEY_1,base64:OLD_KEY_2

Hash passwords:

use Illuminate\Support\Facades\Hash;
 
$password = Hash::make($request->password);

Encrypt decryptable sensitive values:

use Illuminate\Support\Facades\Crypt;
 
$encrypted = Crypt::encryptString($sensitiveValue);

Design pattern angle

Centralize crypto behind a small service/port so you can standardize algorithms, add key-rotation behavior, and swap Laravel Crypt for a KMS/HSM-backed implementation later. Avoid scattering Crypt::encryptString(...) across controllers and models.

interface SensitiveValueCipher
{
public function encrypt(string $plain): string;
public function decrypt(string $cipher): string;
}
 
final class LaravelCipher implements SensitiveValueCipher
{
public function encrypt(string $plain): string
{
return \Illuminate\Support\Facades\Crypt::encryptString($plain);
}
 
public function decrypt(string $cipher): string
{
return \Illuminate\Support\Facades\Crypt::decryptString($cipher);
}
}

References