OWASP Top 10:2025 Technical Verification Standard
WebOTG Hub v4.2
WebOTG-CR-001 • Cryptographic Security Guide

A04:2025 — Cryptographic Failures

Cryptographic Failures focus on weaknesses related to encryption (or lack thereof), which frequently result in exposure of sensitive data, token forgery, session hijacking, or credential compromise.

OWASP Standard
A04:2025
Primary CWEs
CWE-327, CWE-330, CWE-311
Risk Severity
Critical (CVSS 8.5)
Verification Target
Ciphers, Hashing, Key Mgmt

01 Core Cryptographic Flaw Mechanisms

Cryptographic failures occur when systems fail to adequately protect data at rest and in transit. The common architectural failure modes include:

  • Weak or Broken Algorithms: Utilizing obsolete hashing algorithms like MD5/SHA1 for security credentials, or symmetric ciphers like DES/3DES/RC4.
  • Insecure Password Storage: Using single-iteration cryptographic hash functions (e.g. standard SHA-256) instead of memory-hard, work-factored algorithms (Argon2id, bcrypt, PBKDF2).
  • Insecure PRNG (Pseudo-Random Number Generator): Using non-cryptographic RNGs like rand() or Math.random() for tokens, password reset nonces, and session identifiers.
  • Hardcoded and Committed Secrets: Embedding encryption keys, API signing secrets, or private keys directly in source code repositories.
  • Unauthenticated Encryption Modes: Utilizing AES-CBC without HMAC verification, leaving systems vulnerable to padding oracle attacks.

02 Vulnerability Demonstration & Test Triggers

Vulnerable Implementation: Insecure Token Generation & Weak Password Hash

Below is a typical vulnerable PHP backend using predictable PRNG and un-salted, fast hashing.

vulnerable_auth.phpPHP
// VULNERABILITY 1: Fast un-salted hash (susceptible to precomputed rainbow tables)
function storePassword($user, $plainPassword) {
    $hashed = md5($plainPassword); // Broken & fast algorithm
    saveToDb($user, $hashed);
}

// VULNERABILITY 2: Predictable pseudo-random generator for reset tokens
function generatePasswordResetToken($user) {
    // rand() is seeded by time/process state - easily predictable
    $token = md5(rand() . time() . $user);
    saveResetToken($user, $token);
    return $token;
}

Reproduction & Verification Procedure

1
Analyze Token Predictability:

Generate 50 sequential reset tokens and calculate state predictability using PRNG seed reconstruction.

2
Check Transport Encryption:

Inspect network transit headers to verify lack of HSTS and cleartext transmission over HTTP.

curl -I -k http://example.com/api/v1/auth/login # Look for missing Strict-Transport-Security header

03 Audit & Static Code Analysis Rules

Search patterns for detecting cryptographic anti-patterns across codebases:

Anti-Pattern Grep / AST Signature Severity
Weak Hash for Auth md5\(|sha1\(|hash\(['"]sha1 Critical
Insecure PRNG rand\(|mt_rand\(|Math\.random\(\) High
Hardcoded Secrets (api_key|secret_key|jwt_secret)\s*=\s*['"][a-zA-Z0-9_\-]{8,} Critical
Insecure Cipher Mode AES-.*-ECB|DES|RC4 Critical

04 Hardened Remediation Standards

Hardened Cryptographic Implementation

secure_crypto.phpPHP 8+
// 1. Password Hashing using Argon2id or bcrypt with adaptive cost
function secureStorePassword($user, $plainPassword) {
    $hashed = password_hash($plainPassword, PASSWORD_ARGON2ID, [
        'memory_cost' => 65536,
        'time_cost'   => 4,
        'threads'     => 1
    ]);
    saveToDb($user, $hashed);
}

// 2. Cryptographically Secure PRNG Token Generation
function secureGenerateResetToken($user) {
    // 256 bits of CSPRNG entropy
    $randomBytes = random_bytes(32);
    $token = bin2hex($randomBytes);
    
    // Store token hash in database, not raw token
    $tokenHash = hash('sha256', $token);
    saveResetTokenHash($user, $tokenHash, time() + 900); // 15 min TTL
    return $token;
}

// 3. Authenticated Symmetric Encryption (AES-256-GCM)
function secureEncryptPayload(string $plaintext, string $key): array {
    $iv = random_bytes(12); // Standard 96-bit IV for GCM
    $tag = "";
    $ciphertext = openssl_encrypt(
        $plaintext,
        'aes-256-gcm',
        $key,
        OPENSSL_RAW_DATA,
        $iv,
        $tag,
        "",
        16 // 128-bit authentication tag
    );
    return [
        'ciphertext' => base64_encode($ciphertext),
        'iv'         => base64_encode($iv),
        'tag'        => base64_encode($tag)
    ];
}

05 Verification & Compliance Checklist

Check Item Requirement Status
TLS Configuration TLS 1.2 minimum required, TLS 1.3 preferred with modern cipher suites. Mandatory
Password Storage Passlib/Argon2id or bcrypt with cost factor ≥ 12. Mandatory
Key Management No hardcoded secrets; use AWS KMS, HashiCorp Vault, or environment secrets. Mandatory
Data at Rest Sensitive PII encrypted using AES-256-GCM authenticated cipher. Mandatory