CVE-2026-47842

Information Exposure
Affects
Spring Security
in
Spring
No items found.
Versions
7.1.0, >=7.0.0 <=7.0.6, >=6.5.0 <=6.5.11, >=6.4.0 <=6.4.18, >=6.3.0 <=6.3.10, >=6.2.0 <=6.2.8, >=5.8.0 <=5.8.27, >=5.7.0 <=5.7.25, 5.5.8, 4.2.20.RELEASE
Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Spring Security is the authentication and access-control framework for Spring-based applications. Alongside authentication, authorization and protection against common attacks, it ships a standalone cryptography module, spring-security-crypto, whose encryptors, password encoders and key generators are widely used by applications to protect data at rest.

An Information Exposure vulnerability (CVE-2026-47842) has been identified in AesBytesEncryptor, which allows attackers with read access to an encrypted data store to determine when two records hold the same plaintext, correlate encrypted values across rows and across users, and recover protected values by pre-encrypting candidate plaintexts and comparing the resulting ciphertext.

Per OWASP: Cryptographic failures are failures related to cryptography, or its absence, which often lead to the exposure of sensitive data. Initialization vectors that are ignored or reused, or an insecure mode of operation, make ciphertext deterministic and let stored values be correlated or recovered.

This issue affects the spring-security-crypto cryptography module of Spring Security.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the org.springframework.security:spring-security-crypto package in the cryptography module of Spring Security.

AesBytesEncryptor selects its initialization vector generator from the CipherAlgorithm enum when the caller does not supply one. The CBC constant is declared with a shared NULL_IV_GENERATOR, a BytesKeyGenerator whose generateKey() always returns the same 16 zero bytes:

private static final String AES_CBC_ALGORITHM = "AES/CBC/PKCS5Padding";

private static final BytesKeyGenerator NULL_IV_GENERATOR = new BytesKeyGenerator() {

    private final byte[] VALUE = new byte[16];

    @Override
    public int getKeyLength() {
        return this.VALUE.length;
    }

    @Override
    public byte[] generateKey() {
        return this.VALUE;
    }

};

public enum CipherAlgorithm {

    CBC(AES_CBC_ALGORITHM, NULL_IV_GENERATOR),

    GCM(AES_GCM_ALGORITHM, KeyGenerators.secureRandom(16));

    public BytesKeyGenerator defaultIvGenerator() {
        return this.ivGenerator;
    }

}

Every constructor that does not receive an explicit generator falls back to that constant. The two-argument password constructor passes a null generator all the way down, and the secret-key constructor substitutes alg.defaultIvGenerator(), which for CBC is the all-zero generator:

public AesBytesEncryptor(String password, CharSequence salt) {
    this(password, salt, null);
}

public AesBytesEncryptor(String password, CharSequence salt, @Nullable BytesKeyGenerator ivGenerator) {
    this(password, salt, ivGenerator, CipherAlgorithm.CBC);
}

public AesBytesEncryptor(SecretKey secretKey, @Nullable BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
    this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
    this.alg = alg;
    this.encryptor = alg.createCipher();
    this.decryptor = alg.createCipher();
    this.ivGenerator = (ivGenerator != null) ? ivGenerator : alg.defaultIvGenerator();
}

@Override
public byte[] encrypt(byte[] bytes) {
    synchronized (this.encryptor) {
        byte[] iv = this.ivGenerator.generateKey();
        CipherUtils.initCipher(this.encryptor, Cipher.ENCRYPT_MODE, this.secretKey, this.alg.getParameterSpec(iv));
        byte[] encrypted = CipherUtils.doFinal(this.encryptor, bytes);
        return (this.ivGenerator != NULL_IV_GENERATOR) ? EncodingUtils.concatenate(iv, encrypted) : encrypted;
    }
}

Because the same zero IV is reused for every operation, AES in CBC mode becomes deterministic: for a given password and salt, or a given secret key, the same plaintext always produces byte-for-byte identical ciphertext, and the encrypted output carries no per-record randomness at all. The input that reaches the flawed path is any application data handed to encrypt(byte[]) by an encryptor built through the two-argument constructor, through a CBC construction with a null ivGenerator, or through the Encryptors factory methods that wrap them. An attacker who can read the stored ciphertext, for example through a database dump, a backup, a log, or a read-only reporting account, learns which records share a value without ever recovering the key. Where the plaintext space is small or guessable, such as national identifiers, status flags, email addresses, or short tokens, the attacker can encrypt each candidate with the same password and salt and match the output directly, turning the store into a lookup table. The salt is a per-application constant rather than a per-record value, so it does not break this correlation.

Mitigation

Only recent versions of Spring Security receive community support. Older lines are End-of-Life and will not receive public updates to address this issue.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to a currently supported version of Spring Security.
  • Stop using AesBytesEncryptor and the Encryptors factory methods, move to AesCbcBytesEncryptor or AesGcmBytesEncryptor, or supply a non-null ivGenerator when constructing a CBC encryptor, and re-encrypt any data that was written with the all-zero initialization vector.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-47842
PROJECT Affected
Spring Security
Versions Affected
7.1.0, >=7.0.0 <=7.0.6, >=6.5.0 <=6.5.11, >=6.4.0 <=6.4.18, >=6.3.0 <=6.3.10, >=6.2.0 <=6.2.8, >=5.8.0 <=5.8.27, >=5.7.0 <=5.7.25, 5.5.8, 4.2.20.RELEASE
NES Versions Affected
Published date
August 27, 2026
≈ Fix date
Category
Information Exposure
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Spring
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.