Hardcoded Cryptographic Key

ID

javascript.hardcoded_cryptographic_key

Severity

critical

Resource

Predictability

Language

JavaScript

Tags

CWE:321, NIST.SP.800-53, OWASP:2021:A2, PCI-DSS:3.6.3, crypto

Description

Cryptographic keys that are hardcoded into source code can be easily extracted and exploited by malicious actors. This practice compromises the security of the application, as these keys are not changeable without altering the source code.

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 a hardcoded cryptographic key:

const crypto = require('crypto');
// FLAW, hardcoded key
const encryptionKey = "ee69007e6ffc5387924847aa14ac093a";
let iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-128-cbc', Buffer.from(encryptionKey, 'hex'), iv);
let encrypted = cipher.update('out from prying eyes', 'utf8', 'base64');
encrypted += cipher.final('base64');

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.

To fix the vulnerability, take the key contents from an external source, like an environmental variable, instead of hard-coding the key:

const crypto = require('crypto');
// FIXED
const encryptionKey = process.env.ENCRYPTION_KEY;
let iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-128-cbc', Buffer.from(encryptionKey, 'hex'), iv);
let encrypted = cipher.update('out from prying eyes', 'utf8', 'base64');
encrypted += cipher.final('base64');

Configuration

This detector does not need any configuration.

References