pmd / pmd/pmd

[java] InsecureCryptoIv: False negative when a hard-coded IV is constructed through default array initialization

Open
#7,015 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

a:false-negative
Dominant language
Java
Stars
5.5k
Forks
1.6k
Avg merge
1d 19h
Merged PRs (30d)
54

Description

Affects PMD Version: 7.26.0

Rule:
InsecureCryptoIv
https://docs.pmd-code.org/latest/pmd_rules_java_security.html#insecurecryptoiv

Description:
InsecureCryptoIv can detect cases where the IV contents are explicitly specified using an array initializer, for example:

byte[] iv = new byte[] {
    0x00, 0x01, 0x02, 0x03,
    0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c,
    0x0d, 0x0e, 0x0f
};
IvParameterSpec ivSpec = new IvParameterSpec(iv);

However, for the case where a fixed-length array is allocated without an explicit array initializer, the rule does not report a violation:

byte[] iv = new byte[16];
IvParameterSpec ivSpec = new IvParameterSpec(iv);

In Java, newly created arrays of primitive types are automatically initialized with their default values. For byte[], the default value of each element is 0. Therefore, in byte[] iv = new byte[16];, all 16 elements of iv are deterministically set to 0, and the value ultimately passed to IvParameterSpec is also completely determined by the source code:

{0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0}

Although these 0 values do not appear explicitly as literals in the source code, the actual contents of the array are determined by Java's default initialization semantics. Therefore, from the perspective of the rule, this case could also be worth considering for detection. The following test case demonstrates this behavior. The first case is reported by InsecureCryptoIv, whereas the second case does not produce a warning. Therefore, this case could be considered a potential false negative.

Code Sample demonstrating the issue:

// Explicitly initialized IV
package com.example;
import javax.crypto.spec.IvParameterSpec;
public class BadCase {
    public static void main(String[] args) {
        // Hardcoded IV using a fixed byte array
        byte[] iv = new byte[] {
            0x00, 0x01, 0x02, 0x03,
            0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0a, 0x0b, 0x0c,
            0x0d, 0x0e, 0x0f
        }; // [REPORTED LINE]
        IvParameterSpec ivSpec = new IvParameterSpec(iv);
    }
}
// Default array initialization
package com.example;
import javax.crypto.spec.IvParameterSpec;
public class BadCase_Var {
    public static void main(String[] args) {
        byte[] iv = new byte[16];
        IvParameterSpec ivSpec = new IvParameterSpec(iv);// [should be flagged]
    }
}

Expected outcome:
InsecureCryptoIv could consider locally allocated primitive arrays with statically known default values when determining whether an IV is a fixed, hard-coded value. For example:

byte[] iv = new byte[16];
IvParameterSpec ivSpec = new IvParameterSpec(iv);

could be considered by the rule because the contents of iv are deterministically known to be all zeroes. A possible improvement would be to extend the handling of ASTArrayAllocation to account for Java's default array initialization semantics. In particular, the checker could:

  1. Determine whether the allocated array has a statically known length;
  2. Determine whether its element type has a deterministic default value;
  3. Treat an array without an explicit initializer as having those default values;
  4. Propagate the resulting array contents to subsequent uses;
  5. Evaluate whether the resulting IV is a fixed value that should be reported by InsecureCryptoIv.

This would allow the rule to consider fixed IVs even when their constant contents arise implicitly from Java's array initialization semantics rather than from an explicit ASTArrayInitializer.
This is a false-negative case.

Running PMD through: CLI

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the InsecureCryptoIv rule and its handling of ASTArrayAllocation, then reproduce the issue through the CLI using the default-initialized byte array shown in the report. Trace how array contents are propagated to IvParameterSpec. Done means the default-initialized fixed-length array is reported consistently with the explicit initializer case, with regression coverage added where the rule tests are located.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.