Cryptographic Failures (OWASP A02)
Purpose
Provide detection patterns for cryptographic vulnerabilities including weak algorithms, hardcoded secrets, insufficient key lengths, and insecure random number generation.
OWASP Top 10 Mapping
Category: A02 - Cryptographic Failures
CWEs:
- CWE-326: Inadequate Encryption Strength
- CWE-327: Use of Broken or Risky Crypto Algorithm
- CWE-328: Reversible One-Way Hash
- CWE-330: Use of Insufficiently Random Values
- CWE-338: Use of Cryptographically Weak PRNG
- CWE-798: Use of Hardcoded Credentials
When to Use
Activate this skill when:
- Reviewing password hashing implementations
- Checking encryption algorithm usage
- Looking for hardcoded secrets/API keys
- Auditing random number generation
- Verifying key management practices
Weak Hash Algorithms
Detection Patterns
# MD5 usage (broken for security)
grep -rniE "md5\(|MD5\.|hashlib\.md5|MessageDigest.*MD5|crypto\.MD5" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# SHA1 usage (deprecated for security)
grep -rniE "sha1\(|SHA1\.|hashlib\.sha1|MessageDigest.*SHA-1|crypto\.SHA1" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Password hashing with weak algorithms
grep -rniE "password.*md5|password.*sha1|hash.*password.*md5" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
Language-Specific Patterns
Python
# Weak hashing
grep -rniE "hashlib\.md5|hashlib\.sha1" --include="*.py"
# Should use: bcrypt, argon2, scrypt
grep -rniE "bcrypt|argon2|scrypt" --include="*.py"
Vulnerable:
# VULNERABLE: MD5 for passwords
password_hash = hashlib.md5(password.encode()).hexdigest()
Secure:
# SAFE: bcrypt for passwords
password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
Java
# Weak MessageDigest
grep -rniE "MessageDigest\.getInstance.*MD5|MessageDigest\.getInstance.*SHA-1" --include="*.java"
# Should use: BCrypt, Argon2, PBKDF2
grep -rniE "BCrypt|Argon2|PBKDF2|SecretKeyFactory" --include="*.java"
Go
# Weak crypto imports
grep -rniE "crypto/md5|crypto/sha1" --include="*.go"
# Should use: bcrypt, argon2
grep -rniE "golang\.org/x/crypto/bcrypt|golang\.org/x/crypto/argon2" --include="*.go"
PHP
# Weak hashing
grep -rniE "md5\(|sha1\(" --include="*.php"
# Should use: password_hash
grep -rniE "password_hash|PASSWORD_BCRYPT|PASSWORD_ARGON2" --include="*.php"
TypeScript
# Weak crypto
grep -rniE "createHash.*md5|createHash.*sha1" --include="*.ts"
# Should use: bcrypt
grep -rniE "bcrypt\.hash|argon2" --include="*.ts"
Weak Encryption Algorithms
Detection Patterns
# DES (broken)
grep -rniE "DES|DESede|TripleDES" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# RC4 (broken)
grep -rniE "RC4|ARC4|ARCFOUR" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# ECB mode (insecure)
grep -rniE "ECB|AES/ECB|MODE_ECB" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Blowfish (deprecated)
grep -rniE "Blowfish|BLOWFISH" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
Secure Alternatives
| Weak | Secure Alternative |
|---|---|
| DES | AES-256 |
| 3DES | AES-256 |
| RC4 | ChaCha20 or AES-GCM |
| ECB mode | GCM or CBC with HMAC |
| Blowfish | AES-256 |
| RSA-1024 | RSA-2048+ or ECDSA |
Hardcoded Secrets
Detection Patterns
# API keys
grep -rniE "api[_-]?key\s*[=:]\s*['\"][a-zA-Z0-9]{16,}['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Passwords
grep -rniE "password\s*[=:]\s*['\"][^'\"]+['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Secret keys
grep -rniE "secret[_-]?key\s*[=:]\s*['\"][^'\"]+['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# AWS credentials
grep -rniE "AKIA[0-9A-Z]{16}|aws_secret_access_key" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" --include="*.env"
# Private keys
grep -rniE "BEGIN RSA PRIVATE KEY|BEGIN PRIVATE KEY|BEGIN EC PRIVATE KEY" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" --include="*.pem"
# JWT secrets
grep -rniE "jwt[_-]?secret\s*[=:]\s*['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
High-Entropy String Detection
# Long alphanumeric strings (potential secrets)
grep -rniE "['\"][a-zA-Z0-9+/=]{32,}['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
Insecure Random Number Generation
Detection Patterns
# JavaScript/TypeScript - Math.random (NOT cryptographically secure)
grep -rniE "Math\.random\(\)" --include="*.ts" --include="*.js"
# Python - random module (NOT cryptographically secure)
grep -rniE "import random|from random|random\.random|random\.randint" --include="*.py"
# Java - java.util.Random (NOT cryptographically secure)
grep -rniE "new Random\(\)|java\.util\.Random" --include="*.java"
# PHP - rand/mt_rand (NOT cryptographically secure)
grep -rniE "rand\(|mt_rand\(" --include="*.php"
# Go - math/rand (NOT cryptographically secure)
grep -rniE "math/rand|rand\.Intn|rand\.Int\(" --include="*.go"
Secure Alternatives
| Language | Insecure | Secure |
|---|---|---|
| Python | random.random() | secrets.token_bytes() |
| Java | java.util.Random | java.security.SecureRandom |
| Go | math/rand | crypto/rand |
| JavaScript | Math.random() | crypto.randomBytes() |
| PHP | rand(), mt_rand() | random_bytes(), random_int() |
Insufficient Key Length
Detection Patterns
# RSA key size (should be 2048+)
grep -rniE "RSA.*1024|keysize.*1024|KeyPairGenerator.*1024" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# AES key size (should be 256 for sensitive data)
grep -rniE "AES.*128|aes-128" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# HMAC key size
grep -rniE "hmac.*key.*['\"][a-zA-Z0-9]{1,15}['\"]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
Minimum Key Lengths
| Algorithm | Minimum | Recommended |
|---|---|---|
| RSA | 2048 bits | 4096 bits |
| AES | 128 bits | 256 bits |
| ECDSA | 256 bits | 384 bits |
| HMAC | 256 bits | 512 bits |
Predictable IVs/Nonces
Detection Patterns
# Static/zero IV
grep -rniE "iv\s*=\s*['\"]0{16,}['\"]|iv\s*=\s*bytes\(16\)|iv.*\[0,0,0" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Reused nonce
grep -rniE "nonce\s*=\s*['\"]|static.*nonce|const.*nonce" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
Missing Encryption
Detection Patterns
# Plaintext password storage
grep -rniE "password\s*=\s*request|user\.password\s*=\s*" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# HTTP instead of HTTPS
grep -rniE "http://[^localhost]|http://[^127\.0\.0\.1]" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
# Unencrypted database connection
grep -rniE "sslmode=disable|useSSL=false|ssl=false" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" --include="*.env"
Broken Certificate Validation
Detection Patterns
# Go - Skip TLS verification
grep -rniE "InsecureSkipVerify\s*:\s*true" --include="*.go"
# Python - Disable SSL verification
grep -rniE "veri