Insufficient Cryptographic Key Length

ID

javascript.insufficient_crypto_keysize

Severity

critical

Resource

Cryptography

Language

JavaScript

Tags

CWE:326, NIST.SP.800-53, OWASP:2021:A2, PCI-DSS:6.5.3, crypto

Description

Even robust cryptographic algorithms like RSA or AES can be vulnerable to brute-force attacks if implemented with insufficient key lengths.

This detector reports insecure key lengths for symmetric and asymmetric encryption.

Rationale

Hardcoding cryptographic keys in source code is a risky practice as it exposes sensitive information that should remain secret. The concern arises because hardcoded keys are not modifiable without a code change, making them an attractive target for attackers who can access the source code or binaries.

The following is an example of insufficient cryptographic key size for RSA:

const crypto = require('crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 1024, // FLAW
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
});

Remediation

To remediate this vulnerability, cryptographic keys should be managed securely, never hardcoding them in source code. Instead, use environmental variables, configuration files, or dedicated secrets management services that provide secure storage and retrieval of sensitive data.

An alternative is to perform cryptographic operations using an external, managed service. Known as Key Management Services (KMS), they provide different features including key generation and storage, key rotation and lifecycle management, encryption / decryption and other cryptographic operations like digital signatures, key wrapping, secure random number generation, etc.

When generating RSA keys, for example, the key length should be at least 2048 bits:

const crypto = require('crypto');

const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  // FIXED - key length should be at least 2048
  modulusLength: 2048,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem'
  }
});

Configuration

According to your standards for cryptography usage, the minimal key lengths checked by the detector could be configured accordingly.

The detector has the minKeyLengths configurable parameter, with the minimum key length in bits for each algorithm. When set to 0, any use of the algorithm is considered insecure.

properties:
  minKeyLengths:
    # Asymmetric
    # Many sources recommend 3072.
    # RSA / DSA / DH are not quantum-resistant.
    rsa: 2048
    dsa: 2048
    diffie-hellman: 2048
    # Elliptic Curve crypto demands less key lengths.
    # Algorithms like ECDSA are not quantum-resistant
    ec: 256

    # Symmetric
    aes: 128
    tripledes: 168 # three-key DES
    camellia: 128
    serpent: 128
    chacha20: 128
    # ciphers not allowed, deemed weak
    des: 0
    rc2: 0
    rc4: 0
    blowfish: 0

References