criticalA02:2021CWE-327CWE-328CWE-259CWE-331
Cryptographic Failures
Cryptographic failures—previously known as Sensitive Data Exposure—occur when applications fail to properly protect sensitive data through encryption. Most breaches don't come from cracking modern ciphers, but from missing, weak, or misused cryptography: hardcoded keys, outdated algorithms, unencrypted data in transit, and passwords stored with fast hashes.
What are Cryptographic Failures?
Cryptographic failures encompass vulnerabilities related to protecting data confidentiality and integrity. Common issues include:
- Data transmitted in cleartext (HTTP, FTP, SMTP)
- Weak or deprecated algorithms (MD5, SHA1, DES)
- Hardcoded encryption keys and secrets
- Passwords stored with fast/unsalted hashes
- Insufficient entropy in random number generation
Common Vulnerabilities
Weak Password Hashing
javascript
// VULNERABLE: Fast/unsalted hashes
const crypto = require('crypto');
// MD5 - Broken, rainbow tables exist
const hash1 = crypto.createHash('md5').update(password).digest('hex');
// SHA1 - Deprecated, collisions found
const hash2 = crypto.createHash('sha1').update(password).digest('hex');
// SHA256 without salt - Rainbow table vulnerable
const hash3 = crypto.createHash('sha256').update(password).digest('hex');
// All of these can be cracked in seconds with GPU clustersHardcoded Secrets
javascript
// VULNERABLE: Secrets in source code
const JWT_SECRET = 'super-secret-key-123'; // Hardcoded!
const API_KEY = 'sk_live_abc123def456'; // In version control!
const ENCRYPTION_KEY = 'myEncryptionKey'; // Predictable!
// Anyone with code access can extract these
// If code is leaked, all encrypted data is compromisedInsecure Encryption Modes
javascript
// VULNERABLE: ECB mode - patterns visible in ciphertext
const cipher = crypto.createCipheriv('aes-256-ecb', key, null);
// ECB encrypts identical blocks identically
// Patterns in plaintext are visible in ciphertext
// VULNERABLE: Reusing IVs with CBC
const iv = Buffer.alloc(16, 0); // Same IV every time!
const cipher2 = crypto.createCipheriv('aes-256-cbc', key, iv);
// Reusing IVs allows attackers to detect repeated plaintextsMissing TLS/HTTPS
text
# VULNERABLE: Unencrypted protocols
http://api.example.com/login # Credentials sent in cleartext
ftp://files.example.com # Files transferred unencrypted
smtp://mail.example.com # Emails readable by anyone on network
# Attackers on the same network can:
# - Intercept credentials (coffee shop WiFi attack)
# - Steal session cookies
# - Modify data in transitSecure Implementations
1. Secure Password Hashing
javascript
import bcrypt from 'bcrypt';
import argon2 from 'argon2';
// SECURE: bcrypt with cost factor
const SALT_ROUNDS = 12; // Increase as hardware gets faster
async function hashPassword(password) {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password, hash) {
return bcrypt.compare(password, hash);
}
// EVEN BETTER: Argon2id (winner of Password Hashing Competition)
async function hashPasswordArgon2(password) {
return argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 65536, // 64 MB
timeCost: 3, // 3 iterations
parallelism: 4 // 4 threads
});
}2. Proper Encryption
javascript
import crypto from 'crypto';
// SECURE: AES-256-GCM (authenticated encryption)
function encrypt(plaintext, key) {
// Generate random IV for each encryption
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(plaintext, 'utf8', 'base64');
encrypted += cipher.final('base64');
// Get authentication tag
const authTag = cipher.getAuthTag();
// Return IV + authTag + ciphertext
return {
iv: iv.toString('base64'),
authTag: authTag.toString('base64'),
data: encrypted
};
}
function decrypt(encrypted, key) {
const iv = Buffer.from(encrypted.iv, 'base64');
const authTag = Buffer.from(encrypted.authTag, 'base64');
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(encrypted.data, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}3. Secure Key Management
javascript
// SECURE: Keys from environment/secrets manager
const ENCRYPTION_KEY = Buffer.from(
process.env.ENCRYPTION_KEY, // From secrets manager
'hex'
);
// Generate cryptographically secure keys
function generateKey() {
return crypto.randomBytes(32); // 256 bits
}
// For production: Use AWS KMS, HashiCorp Vault, etc.
import { KMSClient, GenerateDataKeyCommand } from '@aws-sdk/client-kms';
async function getDataKey() {
const client = new KMSClient({ region: 'us-east-1' });
const command = new GenerateDataKeyCommand({
KeyId: process.env.KMS_KEY_ID,
KeySpec: 'AES_256'
});
return client.send(command);
}4. Enforce HTTPS
javascript
// Express.js - Redirect HTTP to HTTPS
app.use((req, res, next) => {
if (!req.secure && process.env.NODE_ENV === 'production') {
return res.redirect(`https://${req.headers.host}${req.url}`);
}
next();
});
// Set HSTS header
app.use((req, res, next) => {
res.setHeader(
'Strict-Transport-Security',
'max-age=31536000; includeSubDomains; preload'
);
next();
});
// Secure cookies
app.use(session({
cookie: {
secure: true, // Only over HTTPS
httpOnly: true, // Not accessible via JavaScript
sameSite: 'strict' // CSRF protection
}
}));Algorithm Reference
text
# Password Hashing (use these)
✅ Argon2id - Best choice, memory-hard
✅ bcrypt - Widely supported, proven
✅ scrypt - Memory-hard alternative
✅ PBKDF2 - Acceptable with high iterations (600k+)
# Avoid for passwords
❌ MD5, SHA1, SHA256 (fast, rainbow tables)
❌ Any unsalted hash
# Symmetric Encryption
✅ AES-256-GCM - Authenticated encryption
✅ ChaCha20-Poly1305 - Fast on mobile
❌ AES-ECB - Patterns visible
❌ DES, 3DES - Deprecated, weak
# TLS Versions
✅ TLS 1.3 - Current standard
✅ TLS 1.2 - Acceptable minimum
❌ TLS 1.1 - Deprecated
❌ TLS 1.0 - Deprecated
❌ SSL - BrokenSecurity Checklist
- Use Argon2id or bcrypt for password hashing
- Enforce TLS 1.2+ for all connections
- Enable HSTS with preload
- Never hardcode secrets in source code
- Use secrets managers (Vault, KMS)
- Use AES-256-GCM for symmetric encryption
- Generate unique IVs for each encryption
- Rotate encryption keys periodically
- Use cryptographically secure random generators
Practice Challenges
View allWeak Random
Math.random() for security tokens. Predictable.
ECB Mode
AES in ECB mode. Block manipulation attack.
Padding Oracle
CBC mode with padding oracle. Decrypt without key.
Hash Length Extension
MAC with H(secret || message). Length extension attack.
Weak Hash
MD5 password hashes. Rainbow table time.