Skip to content

Weak Hashing Configuration

What does this mean ?

Weak cryptographic hashes cannot ensure data integrity and should not be utilized in security-critical situations. MD2, MD4, MD5, RIPEMD-160, and SHA-1 are common cryptographic hash algorithms that are frequently used to validate communications and other data. However, due to recent cryptanalysis research revealing fundamental flaws in these algorithms, they should no longer be utilized in security-critical scenarios.

What can happen ?

Incorrect encryption algorithm use can expose sensitive data, lead to key leakage, broken authentication, insecure sessions, and spoofing attacks.

Recommendation

  • Weak hash/encryption algorithms such as MD5, RC4, DES, Blowfish, and SHA1 should not be utilized.
  • The IV (Initialization Vector) must be random and unexpected when using AES128 or AES256.
  • SSH and CBC mode should not be utilized.
  • When using a symmetric encryption technique, the ECB (Electronic Code Book) mode should be avoided.

Sample Code

Vulnerable :

var hashProvider1 = new MD5CryptoServiceProvider(); // Sensitive
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("MD5"); // Sensitive
var hashProvider3 = new SHA1Managed(); // Sensitive
var hashProvider4 = HashAlgorithm.Create("SHA1"); // Sensitive

Non Vulnerable :

var hashProvider1 = new SHA512Managed(); // Compliant
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("SHA512Managed"); // Compliant
var hashProvider3 = HashAlgorithm.Create("SHA512Managed"); // Compliant

Vulnerable :

MessageDigest md = MessageDigest.getInstance("SHA1");  // Sensitive
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Vulnerable

Non Vulnerable :

MessageDigest md = MessageDigest.getInstance("SHA-512"); // Non Sensitive
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); // Non Vulnerable

Vulnerable :

$password = md5($password); // Sensitive
$password = sha1($password);   // Sensitive

Non Vulnerable :

$password = password_hash($password, PASSWORD_BCRYPT); // Compliant

Vulnerable :

const crypto = require("crypto");
const hash = crypto.createHash('sha1');

Non Vulnerable :

const crypto = require("crypto");
const hash = crypto.createHash('sha512');

Vulnerable :

const crypto = require("crypto");
const hash = crypto.createHash('sha1');

Non Vulnerable :

const crypto = require("crypto");
const hash = crypto.createHash('sha512');

Vulnerable :

package main

import (
    "golang.org/x/crypto/bcrypt"
    "fmt"
)

func main() {
    password: = [] byte("password")

    hashedPassword, err: = bcrypt.GenerateFromPassword(password)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(hashedPassword))
}

Non Vulnerable :

package main

import (
    "golang.org/x/crypto/bcrypt"
    "fmt"
)

func main() {
    password: = [] byte("password")

    // Hashing the password with the default cost of 10
    hashedPassword, err: = bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(hashedPassword))
}

Vulnerable :

require 'openssl'

class Encryptor
    attr_accessor :secret_key

    def encrypt_message(message)
        cipher = OpenSSL::Cipher.new('des') # Vulnerable
        cipher.encrypt
        cipher.key = secret_key
        cipher.update(message)
        cipher.final
    end
end

Non Vulnerable :

require 'openssl'

class Encryptor
    attr_accessor :secret_key

    def encrypt_message(message)
        cipher = OpenSSL::Cipher::AES128.new # Non Vulnerable
        cipher.encrypt
        cipher.key = secret_key
        cipher.update(message)
        cipher.final
    end
end

References