Rules that flag potential security flaws.
Table of Contents

HardCodedCryptoKey

Since: PMD 6.4.0

Priority: Medium (3)

Do not use hard-coded values for cryptographic operations. Store keys outside of source code or generate it from a random source.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule

Example(s):

public class HardCodedCryptoKeyExample {
    void good() throws Exception {
        // loading the key via properties from outside of the source code
        SecretKey secretKey1 = new SecretKeySpec(Properties.getKey(), "AES");

        // generating a fresh key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(256);
        SecretKey secretKey2 = keyGenerator.generateKey();

        // generating from a password, the password is from outside the source code
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(Properties.getPassword().toCharArray(), Properties.getSalt().getBytes(), 65536, 256);
        SecretKey secretKey3 = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
    }

    void bad() {
        SecretKey secretKey1 = new SecretKeySpec("my secret here".getBytes(), "AES");

        byte[] key2 = new byte[] { 1, 2, 3 };
        SecretKey secretKey2 = new SecretKeySpec(key2, "AES");

        byte[] key3 = new byte[32];
        SecretKey secretKey3 = new SecretKeySpec(key3, "AES");
    }
}

Use this rule by referencing it:

<rule ref="category/java/security.xml/HardCodedCryptoKey" />

InsecureCryptoIv

Since: PMD 6.3.0

Priority: Medium (3)

Do not use hard coded initialization vector in cryptographic operations. Use a randomly generated IV.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule

Example(s):

public class InsecureCryptoIvExample {
    void good(SecretKey key) throws Exception {
        SecureRandom random = SecureRandom.getInstanceStrong();
        byte[] iv = new byte[Cipher.getInstance("AES").getBlockSize()];
        random.nextBytes(iv);
        IvParameterSpec ivParam = new IvParameterSpec(iv);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, ivParam);
    }

    void bad() {
        byte[] iv1 = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, };
        IvParameterSpec ivParam1 = new IvParameterSpec(iv1);

        byte[] iv2 = new byte[16];
        IvParameterSpec ivParam2 = new IvParameterSpec(iv2);

        byte[] iv3 = "secret iv in here".getBytes();
        IvParameterSpec ivParam3 = new IvParameterSpec(iv3);
    }
}

Use this rule by referencing it:

<rule ref="category/java/security.xml/InsecureCryptoIv" />