ankur@sec:~$

$ cat owasp/a04.md

A04:2025

Cryptographic Failures

Sensitive data is stored or sent without proper protection - or "protected" with something guessable.

## 1 · why it happens

Most crypto bugs are not broken algorithms. They are developers using the wrong tool: Math.random() for reset tokens, MD5 for passwords, a JWT secret like "secret", or keys committed next to the code they protect.

Once an attacker can predict a token or crack a hash offline, every other control in the app is bypassed.

# JavaScript

✗ vulnerable
const resetToken = Math.random().toString(36).slice(2);   // predictable
const hash = crypto.createHash('md5').update(password).digest('hex');
jwt.sign(payload, 'secret');
✓ fixed
const resetToken = crypto.randomBytes(32).toString('hex');
const hash = await bcrypt.hash(password, 12);           // or argon2
jwt.sign(payload, process.env.JWT_SECRET, { algorithm: 'HS256', expiresIn: '15m' });
// JWT_SECRET: 32+ random bytes, from a secret manager

# C#

✗ vulnerable
var token = new Random().Next().ToString();          // predictable
using var md5 = MD5.Create();
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
✓ fixed
var token = Convert.ToHexString(RandomNumberGenerator.GetBytes(32));
var hasher = new PasswordHasher<User>();                 // PBKDF2 with salt
var hash = hasher.HashPassword(user, password);

## 2 · how attackers find it from outside

public sourcewhat it tells them
Public GitHub repos & historyHard-coded JWT secrets, API keys and private keys - even if deleted in a later commit.
JavaScript bundlesClient-side "encryption" keys and API keys shipped to every browser.
Certificate & TLS checks (crt.name / SSL Labs)Old protocols and certificates on forgotten subdomains.

→ all OSINT sources · run them on yourself

## 3 · how it's abused

⚠ Recon your own assets, or targets you have written permission to test. Passive OSINT reads public data, but using it to target someone else's systems can still be illegal or against their terms. Examples on this site use example.com placeholders.

hashcat -a 0 -m 16500 jwt.txt wordlist.txt

Cracks the secret of a captured JWT offline. A weak secret means the attacker can sign their own tokens.

{"alg":"none"}

Some libraries accepted unsigned tokens when the header said "none" (CVE-2015-9235).

Payload examples adapted from PayloadsAllTheThings (MIT, © Swissky). Full lists:Insecure Randomness · JSON Web Token · API Key Leaks

## 4 · fix

## 5 · detect

fix at source

Gitleaks

Find secrets in your git history before someone else does.

fix at source

TruffleHog

Find secrets and check whether they still work.

fix at source

Bearer

Static analysis that follows sensitive data through your code.

Official description: OWASP A04:2025 Cryptographic Failures