Laravel Weak Encryption Cipher: How to Ensure AES-256-CBC Is Configured Correctly

A non-standard cipher in config/app.php weakens all encryption in your application. Verify AES-256-CBC is set and your APP_KEY matches.

Medium severity Application Security Updated 2026-05-01 Markdown

Symmetric encryption in Laravel uses the Encrypter class, which combines a cipher algorithm, an encryption key, and an initialization vector (IV) to transform plaintext into ciphertext. The cipher configured in config/app.php determines the algorithm used for all encryption operations: session cookies, encrypted model attributes, and values passed through Crypt::encrypt(). Laravel defaults to AES-256-CBC — AES with a 256-bit key in Cipher Block Chaining mode — which provides strong, widely-vetted symmetric encryption.

Changing to a weaker cipher reduces the security of every encrypted value in the application. AES-128-CBC uses a 128-bit key instead of 256-bit, halving the key space and reducing the computational work required for a brute-force attack. Non-standard ciphers or ciphers not supported by Laravel throw exceptions or silently fall back to defaults depending on the PHP version. A mismatch between the cipher and the key length (such as using a 32-byte key with AES-128-CBC) causes encryption errors that may result in plaintext storage of values that should be encrypted.

The most common way this misconfiguration appears is through legacy migrations from older Laravel versions. Laravel 5.x used AES-128-CBC with a 16-byte key as the default. Applications that migrated from Laravel 5 to 6+ without updating the cipher configuration continue using the weaker setting. Some developers also modify the cipher when troubleshooting encryption errors rather than diagnosing the actual key length mismatch. The correct fix for any encryption error is to verify the cipher and key length match, not to change the cipher to something that accepts the wrong key length.

The Problem

Laravel's encryption system uses the cipher configured in config/app.php. The default and recommended cipher is AES-256-CBC, which provides strong symmetric encryption. If this setting is changed to a weaker cipher (like AES-128-CBC, DES, or a custom value), all encrypted data — including sessions, cookies, and Crypt::encrypt() values — uses weaker protection. A mismatched cipher and key length also causes encryption failures.

How to Fix

  1. 1

    Verify your cipher configuration

    Check config/app.php:

    'cipher' => 'AES-256-CBC',

    This should be exactly AES-256-CBC (the Laravel default). If you see AES-128-CBC, DES, or any other value, change it back.

    Also verify via artisan:

    php artisan tinker
    >>> config('app.cipher')
    # Should output: AES-256-CBC
  2. 2

    Ensure your APP_KEY matches the cipher

    AES-256-CBC requires a 32-byte key. AES-128-CBC requires a 16-byte key.

    Verify your key length:

    php artisan tinker
    >>> strlen(base64_decode(Str::after(config('app.key'), 'base64:')))
    # Should output: 32 for AES-256-CBC

    If the key length is wrong, generate a new key:

    php artisan key:generate

    Warning: Regenerating the key invalidates all existing encrypted data and sessions.

  3. 3

    Do not override the cipher in environment files

    Check that .env does not contain a cipher override:

    grep -i cipher .env
    The cipher should only be set in config/app.php, not in .env. If present in .env, remove it and let the config file handle it:
    // config/app.php — correct
    'cipher' => 'AES-256-CBC',
    // Do NOT put in .env
    // APP_CIPHER=AES-128-CBC  ← remove this

How to Verify

Verify encryption works correctly:

php artisan tinker
>>> encrypt('test')
# Should return a long encrypted string
>>> decrypt(encrypt('test'))
# Should return: test

Run php artisan stackshield:scan --check=SS011 to verify.

Prevention

Never modify the cipher setting from the Laravel default. If you upgraded from an older Laravel version that used AES-128-CBC, migrate to AES-256-CBC by regenerating the key and re-encrypting any stored data.

Frequently Asked Questions

Is AES-128-CBC insecure?

AES-128-CBC is not broken, but AES-256-CBC provides a larger margin of safety. Since Laravel defaults to AES-256-CBC and there is no performance difference for typical use, there is no reason to use the weaker option.

What happens if I change the cipher?

All data encrypted with the old cipher becomes undecryptable. Sessions are invalidated, encrypted database columns become unreadable, and signed cookies fail. Only change the cipher if you also regenerate the key and re-encrypt all data.

What is the difference between AES-256-CBC and AES-256-GCM?

AES-256-GCM (Galois/Counter Mode) is authenticated encryption — it provides both confidentiality and integrity verification, meaning an attacker cannot modify encrypted data without detection. AES-256-CBC provides confidentiality but is susceptible to padding oracle attacks without an integrity check. Laravel's CBC implementation includes an HMAC to provide integrity, making it secure for practical purposes, but GCM is considered the more modern standard.

Does the cipher setting in config/app.php affect password hashing?

No. Password hashing uses Hash::make(), which invokes bcrypt or argon2 — entirely separate from the encryption system and not using the APP_KEY or cipher configuration. The cipher setting only affects values encrypted with Crypt::encrypt(), encrypt(), encrypted Eloquent model casts, and session/cookie data. Passwords are hashed (one-way), not encrypted (reversible).

What happens if I have data encrypted with AES-128-CBC and switch to AES-256-CBC?

Data encrypted under the old cipher cannot be decrypted under the new cipher — they use different algorithms and key lengths. Before changing the cipher, decrypt all stored encrypted values using the old cipher and key, change the configuration, then re-encrypt with the new settings. This is a significant database migration that should be planned, tested in staging, and executed with the application in maintenance mode.

Free security check

Is your Laravel app exposed right now?

34% of Laravel apps we scan have at least one critical issue. Most teams don't find out until something breaks. Our free scan checks your live application in under 60 seconds.

18% have debug mode on
72% missing security headers
12% have exposed .env
Scan My App Free No signup required. Results in 60 seconds.