java.lang.security.audit.bad-hexa-conversion.bad-hexa-conversion

Community Favorite
profile photo of returntocorpreturntocorp
Author
73,396
Download Count*

'Integer.toHexString()' strips leading zeroes from each byte if read byte-by-byte. This mistake weakens the hash value computed since it introduces more collisions. Use 'String.format("%02X", ...)' instead.

Run Locally

Run in CI

Defintion

rules:
  - id: bad-hexa-conversion
    metadata:
      cwe:
        - "CWE-704: Incorrect Type Conversion or Cast"
      owasp: A03:2017 - Sensitive Data Exposure
      source-rule-url: https://find-sec-bugs.github.io/bugs.htm#BAD_HEXA_CONVERSION
      category: security
      technology:
        - java
      references:
        - https://cwe.mitre.org/data/definitions/704.html
      subcategory:
        - audit
      likelihood: LOW
      impact: LOW
      confidence: LOW
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    message: "'Integer.toHexString()' strips leading zeroes from each byte if read
      byte-by-byte. This mistake weakens the hash value computed since it
      introduces more collisions. Use 'String.format(\"%02X\", ...)' instead."
    severity: WARNING
    languages:
      - java
    pattern: |-
      $X $METHOD(...) {
        ...
        MessageDigest $MD = ...;
        ...
        $MD.digest(...);
        ...
        Integer.toHexString(...);
      }

Examples

bad-hexa-conversion.java

package testcode.crypto;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class BadHexa {
    public static void main(String[] args) throws Exception {
        String good = goodHash("12345");
        String bad = badHash("12345");
        System.out.println(String.format("%s (len=%d) != %s (len=%d)", good, good.length(), bad, bad.length()));
    }

    // ok: bad-hexa-conversion
    public static String goodHash(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] resultBytes = md.digest(password.getBytes("UTF-8"));

        StringBuilder stringBuilder = new StringBuilder();
        for (byte b : resultBytes) {
            stringBuilder.append(String.format("%02X", b));
        }

        return stringBuilder.toString();
    }

    // ruleid: bad-hexa-conversion
    public static String badHash(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] resultBytes = md.digest(password.getBytes("UTF-8"));

        StringBuilder stringBuilder = new StringBuilder();
        for (byte b : resultBytes) {
            stringBuilder.append(Integer.toHexString(b & 0xFF));
        }

        return stringBuilder.toString();
    }
}