Cryptographic Failures Testing: How to Find OWASP A02 Vulnerabilities

OWASP renamed this category in 2021. It used to be called "Sensitive Data Exposure" — a name that described the symptom rather than the cause. The new name, Cryptographic Failures, is more precise: data gets exposed because the cryptography protecting it was absent, broken, or misconfigured.

That reframing matters for testing. You're not just looking for places where sensitive data leaks. You're looking for places where the cryptographic controls that should prevent that leak are weak, missing, or bypassed. Those are different questions, and they require different techniques.

This guide covers how to test for cryptographic failures systematically — from TLS configuration to password storage to application-layer encryption choices — and what automated tools can and cannot surface.

What Cryptographic Failures Actually Covers

A02 is broad. The common thread is that sensitive data — credentials, tokens, PII, financial records, health data — is either transmitted or stored without adequate cryptographic protection. The failures cluster into four distinct patterns:

Transport layer failures — using outdated TLS versions (1.0, 1.1), weak cipher suites, self-signed certificates, or no HTTPS at all. The data is in transit and readable to anyone on the network path.

Cryptographic algorithm failures — using MD5 or SHA1 for password hashing, AES in ECB mode, static IVs, hardcoded keys, or rolling custom crypto. The data is "encrypted" but recoverable.

Key management failures — keys embedded in source code, stored in plaintext configuration files, never rotated, or shared across environments. The algorithm is fine; the key material is not.

Data classification failures — sensitive data that isn't identified as sensitive, so it ends up in logs, URLs, error messages, or cookies without the protection it needs. No one made a deliberate decision to encrypt it because no one flagged it as requiring encryption.

Common Vulnerability Patterns

Weak TLS configuration The server accepts TLS 1.0 or TLS 1.1 connections, negotiates export-grade or NULL cipher suites, uses RC4, or presents a self-signed certificate without a trust chain. Clients that support these protocols will downgrade, and a network attacker can force the downgrade. TLS 1.0 is vulnerable to BEAST and POODLE; TLS 1.1 lacks modern AEAD cipher support.
Cleartext data transmission The application serves login forms or sensitive endpoints over HTTP, performs HTTP-to-HTTPS redirects without HSTS, or allows mixed content (HTTPS page loading HTTP resources). Without HSTS, an attacker who intercepts the initial HTTP request can prevent the redirect entirely. Mixed content downgrades the effective security of the HTTPS page.
Weak password hashing Passwords stored as MD5 or SHA1 hashes — with or without salt — are crackable at billions of attempts per second on commodity hardware. bcrypt with a cost factor below 10 is similarly fast to attack. SHA256 and SHA512 are fast by design; speed is the wrong property for a password hash. Argon2id, bcrypt (cost ≥ 12), and scrypt are the right choices.
Insecure cryptographic storage AES-ECB mode leaks structural patterns in the plaintext — identical input blocks produce identical output blocks. Static IVs in CBC mode allow IV reuse attacks. Weak key derivation (deriving a key directly from a password with no KDF, or using PBKDF2 with a low iteration count) makes brute-force practical. Hardcoded encryption keys in source code or config files that ship with the application.
Sensitive data in logs, URLs, and cookies API keys, session tokens, and PII landing in application logs. Credentials or tokens passed as URL query parameters (logged by proxies, web servers, and browser history). Session tokens in cookies without the Secure and HttpOnly flags. Sensitive data in error messages returned to the client. These aren't algorithm failures — they're data classification failures that lead to exposure.

Testing TLS Configuration

testssl.sh is the right tool for systematic TLS testing. It checks protocol support, cipher suites, certificate validity, and a wide range of known vulnerabilities (BEAST, POODLE, DROWN, Heartbleed, ROBOT) in a single run.

# Full scan — checks protocols, ciphers, and known CVEs
testssl.sh https://target.example.com

# Check only protocols and ciphers (faster)
testssl.sh --protocols --cipher-per-proto https://target.example.com

# Output to JSON for pipeline integration
testssl.sh --jsonfile results.json https://target.example.com

# Check a non-standard port
testssl.sh https://target.example.com:8443

Key findings to look for in the output:

For quick spot-checks, nmap's ssl-enum-ciphers script enumerates supported cipher suites by protocol version:

# Enumerate supported ciphers, grouped by TLS version
nmap --script ssl-enum-ciphers -p 443 target.example.com

# Check multiple ports
nmap --script ssl-enum-ciphers -p 443,8443,8080 target.example.com

The SSL Labs API provides a comprehensive graded assessment. Anything below an A rating warrants investigation — a B usually means TLS 1.0/1.1 is still enabled, a C or below indicates serious configuration problems.

Testing for Cleartext Credentials and Missing HSTS

The most straightforward check: visit the login page over HTTP (http:// instead of https://). Three outcomes to distinguish:

  1. Immediate redirect to HTTPS — good, but check the response headers of the redirect for Strict-Transport-Security
  2. Login form served over HTTP — critical finding. Credentials submitted on this form are transmitted in cleartext.
  3. Page loads over HTTP with mixed content — the form action may submit to HTTPS, but other resources loaded insecurely reduce the effective security

To confirm HSTS is properly configured:

# Check HSTS header presence and max-age
curl -sI https://target.example.com | grep -i strict-transport

# Expected output:
# strict-transport-security: max-age=31536000; includeSubDomains; preload

# Check what happens on HTTP — should redirect, not serve content
curl -sI http://target.example.com | head -5

A max-age below 1 year (31536000 seconds) is worth noting. HSTS without includeSubDomains leaves subdomains exposed. HSTS without preload doesn't protect first-time visitors before they've seen the header.

Also check for mixed content using browser developer tools. The console will flag any HTTP resources loaded on an HTTPS page. A more thorough check: intercept responses with a proxy and search for http:// references in HTML source, JavaScript, and CSS.

Testing Password Storage

You generally can't directly inspect how passwords are stored without database access. But there are indirect signals that reveal the hashing scheme in use.

Response time analysis

bcrypt's cost factor is intentional latency. A login request that verifies a bcrypt hash will take 100–300ms on the server. A login that uses MD5 or SHA256 will respond in under 10ms. Measure the time difference between a valid login and an invalid login attempt — if both respond in under 20ms, the application is not using a slow password hash.

# Time a valid login attempt
time curl -s -o /dev/null -X POST https://target.example.com/login \
  -d "username=testuser&password=correctpassword"

# Time an invalid login attempt
time curl -s -o /dev/null -X POST https://target.example.com/login \
  -d "username=testuser&password=wrongpassword"

Note: this is indirect evidence, not confirmation. A fast response could also mean the user lookup failed before hashing (username enumeration side-channel). Check both a known-valid username with a wrong password and an unknown username.

Password reset flow observation

Password reset flows sometimes reveal storage mechanisms. If the application emails you your existing password in plaintext, it is stored in plaintext — the most severe case. If the reset link doesn't expire or is guessable, that's a separate finding. Observe whether the reset token appears in the URL (logged by servers and proxies) or in a POST body.

Error message analysis

Some applications leak hashes in error responses, debug output, or API responses. Test password reset and profile endpoints for any field that might contain a stored hash value.

Testing for Sensitive Data Exposure

HTTP response headers

Inspect response headers on every endpoint. Look for:

# Inspect all response headers from the login endpoint
curl -sI https://target.example.com/login

# Check cookie flags specifically
curl -sc /dev/null https://target.example.com/login -v 2>&1 | grep -i 'set-cookie'

URL parameter analysis

Audit the application for sensitive data passed in query strings. Common findings:

Error messages and stack traces

Trigger error conditions deliberately — submit malformed input, access non-existent resources, send invalid content types. Production applications should return generic error messages. Stack traces, SQL queries, file paths, and internal hostnames in error responses are information disclosure findings that often co-occur with cryptographic failures.

JavaScript source analysis

Frontend JavaScript frequently contains hardcoded API keys, tokens, and credentials that belong server-side. Check all .js files loaded by the application for:

# In browser devtools, search loaded scripts for common patterns
# Or download and grep:
curl -s https://target.example.com/static/app.js | grep -iE \
  '(api_key|apikey|secret|password|token|private_key)\s*[=:]\s*["\x27][^"\x27]{8,}'

What Automated DAST Tools Catch — and What They Miss

Cryptographic failure testing is one of the stronger areas for automated scanners, precisely because much of it is observable at the network layer. TLS configuration is entirely external — you don't need application-level access to test it.

Finding type Automated detection Notes
TLS 1.0 / TLS 1.1 support Excellent Fully automated; protocol negotiation is deterministic
Weak or NULL cipher suites Excellent Enumerable by probing the TLS handshake
Missing HSTS header Excellent Simple header presence check
Missing Secure / HttpOnly cookie flags Good Requires authenticated session to see session cookies
HTTP login form (cleartext credentials) Good Scanner must recognise the form as a login form
Self-signed or expired certificates Good Certificate inspection is standard
Sensitive data in URL parameters Moderate Scanner must know which parameter values are "sensitive"
Hardcoded secrets in JavaScript Moderate Pattern matching helps; novel key formats are missed
Password hashing algorithm Poor Response time is an indirect signal; confirmation requires source access
AES-ECB mode / weak IV usage Poor Application-layer encryption choices aren't visible at the HTTP layer
Key management failures Very limited Keys in config files require source or filesystem access

The pattern is consistent: anything observable at the network or HTTP layer (TLS, headers, cookies, URLs) is well-covered by automated scanning. Anything inside the application — how passwords are hashed, how data is encrypted at rest, where keys are stored — requires source code review or authenticated access to the application's internals.

How Ironimo Approaches Cryptographic Failure Detection

Ironimo's scanning pipeline covers the externally observable surface comprehensively. For every target, the scanner:

Where Ironimo cannot reach without source access — password hashing algorithms, at-rest encryption choices, key storage — findings include guidance on what to verify manually and what questions to ask your development team.

Key Takeaways

Ironimo tests your application's TLS configuration, security headers, cookie flags, and sensitive data patterns using the same Kali Linux toolset professional pentesters run against production targets — across every endpoint, not just your homepage.

Schedule on-demand or recurring scans. Each finding includes the exact request, the response that confirms it, and a remediation path your team can act on immediately.

Start free scan
← Back to blog