• Zero-Day Wire
  • Posts
  • Defend the Web (Week 2): Authentication & Session Management Defense

Defend the Web (Week 2): Authentication & Session Management Defense

How to Build Secure Auth Systems & Stop Credential Attacks

πŸ›‘οΈ Week 2: Secure Authentication & Session Management

Defend the Web: Part 2 of 8

Welcome to Defensive Wednesday.

Hey πŸ‘‹

Yesterday we broke authentication. You learned how to crack passwords, hijack sessions, and manipulate JWT tokens.

If you missed Week 2 Offensive, read it here πŸ‘‰ link

Today we flip the script. You're building authentication that actually holds up.

Reality check: 81% of data breaches involve weak or stolen credentials. Authentication is target #1.

🧠 What Makes Authentication Secure?

Secure auth = multiple layers:

  • Strong credential policies

  • Proper session management

  • Multi-factor authentication

  • Rate limiting & monitoring

The goal: Make it so hard attackers move on.

πŸ”§ The Defense Process

Step 1: Password Security Done Right

Enforce Strong Policies

Minimum requirements:

  • 12+ characters (length > complexity)

  • Mix of uppercase, lowercase, numbers, symbols

  • Block common passwords

Hash Passwords Properly

Use bcrypt or Argon2:

import bcrypt

# Hash password
password = b"user_password"
hashed = bcrypt.hashpw(password, bcrypt.gensalt(rounds=12))

# Verify
if bcrypt.checkpw(password, hashed):
    print("Valid")

Why? They're slow by design (~100ms per hash). Makes brute force impractical.

Check Against Breaches

Use Have I Been Pwned API:

import hashlib, requests

def is_pwned(password):
    sha1 = hashlib.sha1(password.encode()).hexdigest().upper()
    prefix = sha1[:5]
    url = f"https://api.pwnedpasswords.com/range/{prefix}"
    return sha1[5:] in requests.get(url).text

Step 2: Block Brute Force

Rate Limiting

Limit attempts per IP and account:

from flask_limiter import Limiter

@app.route("/login")
@limiter.limit("5 per minute")
def login():
    pass

Account Lockout

Lock after 5 failed attempts for 15 minutes.

CAPTCHA After Failures

Add reCAPTCHA after 3 failed logins.

Progressive Delays

# 1st fail: 0s, 2nd: 2s, 3rd: 4s, 4th: 8s...
delay = min(2 ** (fails - 1), 30)
time.sleep(delay)

Step 3: Prevent Username Enumeration

Generic Errors

❌ "User not found"
βœ… "Invalid username or password"

Consistent Response Times

Add artificial delays so valid/invalid usernames take the same time.

Step 4: Secure Session Management

Strong Session Tokens

import secrets
token = secrets.token_urlsafe(32)

Never use predictable tokens.

Secure Cookie Flags

response.set_cookie(
    'session_id', token,
    httponly=True,   # JS can't access
    secure=True,     # HTTPS only
    samesite='Strict' # Prevents CSRF
)

Session Expiration

Implement idle timeout (1 hour) + absolute timeout (24 hours).

Regenerate IDs After Login

Prevents session fixation:

old_session = request.cookies.get('session_id')
delete_session(old_session)
new_session = secrets.token_urlsafe(32)

Step 5: Defend Against JWT Attacks

Use Strong Algorithms

❌ Never: none algorithm
βœ… Use: HS256 with 32+ byte secrets or RS256

Validate Everything

import jwt

payload = jwt.decode(
    token, secret,
    algorithms=['HS256'],
    options={'verify_signature': True, 'verify_exp': True}
)

Short Expiration

  • Access tokens: 15 minutes

  • Refresh tokens: 7 days

Token Revocation

Use Redis blacklist:

import redis
r = redis.Redis()

def logout(token):
    exp = jwt.decode(token, secret)['exp']
    r.setex(f"blacklist:{token}", int(exp - time.time()), "1")

Step 6: Implement MFA

TOTP (Google Authenticator)

import pyotp

secret = pyotp.random_base32()
totp = pyotp.TOTP(secret)

# Verify code
totp.verify(user_code, valid_window=1)

Backup Codes

Generate 10 one-time codes, hash them, show once.

Prevent MFA Bypass

  • No session tokens before MFA verification

  • Rate limit MFA attempts (3 max)

  • Invalidate codes after use

Step 7: Monitor & Detect

Log Everything

log_entry = {
    'timestamp': time.time(),
    'event': 'login',
    'username': username,
    'ip': request.remote_addr,
    'success': True
}

Watch For:

  • Logins from new locations

  • Multiple failed attempts

  • Impossible travel (5000km in 1 hour)

  • Simultaneous logins from different IPs

Geolocation Checks

def check_impossible_travel(user_id, current_ip):
    last_login = get_last_login(user_id)
    distance = calculate_distance(last_ip, current_ip)
    time_diff = time.time() - last_login['time']
    
    if distance > 5000 and time_diff < 3600:
        lock_account(user_id)

Step 8: Secure Password Reset

Time-Limited Tokens

import secrets, hashlib

raw_token = secrets.token_urlsafe(32)
token_hash = hashlib.sha256(raw_token.encode()).hexdigest()
store_reset_token(user_id, token_hash, expires_in=3600)

Invalidate After Use

Delete token after password reset. Invalidate all sessions.

Prevent Email Enumeration

Always return: "If that email exists, we've sent a reset link."

Step 9: SQL Injection Prevention

Use Parameterized Queries

❌ Never:

f"SELECT * FROM users WHERE username='{user}'"

βœ… Always:

cursor.execute("SELECT * FROM users WHERE username=?", (user,))

Use ORMs

SQLAlchemy, Django ORM, etc. handle this automatically.

Step 10: Secure OAuth

Validate redirect_uri

Whitelist allowed redirect URIs.

Use state Parameter

state = secrets.token_urlsafe(32)
session['oauth_state'] = state

# On callback
if request.args.get('state') != session.get('oauth_state'):
    return "CSRF detected"

πŸ› οΈ Tool List

Password Security

Rate Limiting

Session Management

JWT

MFA

Monitoring

βœ… Week 2 Checklist

  • [ ] Strong password policies (12+ chars)

  • [ ] bcrypt/Argon2 hashing

  • [ ] HIBP breach checking

  • [ ] Rate limiting (5 attempts/min)

  • [ ] Account lockout after 5 fails

  • [ ] Generic error messages

  • [ ] Cryptographically random tokens

  • [ ] HttpOnly/Secure/SameSite cookies

  • [ ] Session expiration (idle + absolute)

  • [ ] Session regeneration after login

  • [ ] JWT signature validation

  • [ ] Short JWT expiration (15 min)

  • [ ] MFA implemented (TOTP)

  • [ ] Authentication logging

  • [ ] Suspicious activity monitoring

  • [ ] Secure password reset flow

  • [ ] Parameterized queries only

🎯 Key Takeaways

βœ… Passwords aren't enough β€” Use MFA always
βœ… Hash, don't encrypt β€” bcrypt/Argon2 with high cost
βœ… Protect session tokens β€” HttpOnly, Secure, SameSite flags
βœ… Rate limit everything β€” Stop brute force automation
βœ… Generic error messages β€” No username enumeration
βœ… Log everything β€” Can't defend what you can't see
βœ… Test yourself β€” Use attacker tools on your own systems
βœ… Defense is continuous β€” Monitor, update, stay vigilant

Next Tuesday: Access Control & IDOR attacks
Next Wednesday: Proper access control implementation

Stay secure πŸ›‘οΈ

Your Feedback Matters

Did You Enjoy This Week’s Defensive Tutorial?

Login or Subscribe to participate in polls.

β€” Zwire ✌️

P.S. Questions? Reply to this email. I read everything.

Reply

or to participate.