v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: MEDIUM auth.java.crypto.ecb-mode

A JCA Cipher is being created in ECB mode (or with a bare algorithm alias that defaults to ECB).

Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.

Why this matters

ECB encrypts each block independently, so identical plaintext blocks produce identical ciphertext blocks. It is deterministic and leaks structure/patterns of the plaintext (CWE-327). Cipher.getInstance("AES"), "DES", "DESede", or "Blowfish" with no mode specified silently falls back to ECB as well.

Use an authenticated mode: Cipher.getInstance("AES/GCM/NoPadding") with a unique 12-byte IV per message. At minimum use CBC with a random IV plus a separate HMAC (encrypt-then-MAC). Never use ECB or a bare cipher alias.

VULNERABLE
vulnerable.java
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.security.NoSuchAlgorithmException;

class EcbModeVulnerable {

    Cipher explicitEcb() throws NoSuchAlgorithmException, NoSuchPaddingException {
        // ruleid: auth.java.crypto.ecb-mode
        return Cipher.getInstance("AES/ECB/PKCS5Padding");
    }

    Cipher bareAesAlias() throws NoSuchAlgorithmException, NoSuchPaddingException {
        // ruleid: auth.java.crypto.ecb-mode
        return Cipher.getInstance("AES");
    }

    Cipher bareDesAlias() throws NoSuchAlgorithmException, NoSuchPaddingException {
        // ruleid: auth.java.crypto.ecb-mode
        return Cipher.getInstance("DES");
    }
}
SAFE
safe.java
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.security.NoSuchAlgorithmException;

class EcbModeSafe {

    // ok: auth.java.crypto.ecb-mode -- authenticated GCM mode
    Cipher gcm() throws NoSuchAlgorithmException, NoSuchPaddingException {
        return Cipher.getInstance("AES/GCM/NoPadding");
    }

    // ok: auth.java.crypto.ecb-mode -- CBC with explicit padding (use a random IV)
    Cipher cbc() throws NoSuchAlgorithmException, NoSuchPaddingException {
        return Cipher.getInstance("AES/CBC/PKCS5Padding");
    }

    // ok: auth.java.crypto.ecb-mode -- asymmetric RSA with OAEP, not symmetric block ECB
    Cipher rsa() throws NoSuchAlgorithmException, NoSuchPaddingException {
        return Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
    }
}

Suppressing this rule

If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.

// oauthlint-disable-next-line auth.java.crypto.ecb-mode -- <reason>

References

https://cwe.mitre.org/data/definitions/327.html ↗https://owasp.org/Top10/A02_2021-Cryptographic_Failures/ ↗https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html ↗