Stop Cookie Replay Attacks

Tags:

TL;DR

Cookie replay attacks happen when someone steals your cookie and uses it to pretend to be you. This guide shows how to add extra security layers – using a unique ‘nonce’ (number used once) with each login, checking the user’s IP address, and setting secure flags on cookies – to make these attacks much harder.

How Replay Attacks Work

Imagine you log into your bank. Your browser gets a cookie that proves you’re logged in. If someone steals this cookie, they can use it to access your account without needing your password. That’s a replay attack. We need ways to make sure the cookie isn’t used after it *should* be.

Solution: Layered Security

We’ll combine three techniques for better protection:

Unique Nonce per Login
IP Address Checking (with caution)
Secure Cookie Flags

1. Unique Nonce per Login

A nonce is a random, unique number generated for each login session. We store this on the server and check it with every request.

Generate the Nonce: When a user logs in successfully, create a strong random string (e.g., using a UUID).
Store the Nonce: Save this nonce associated with the user’s session on your server-side storage (database, cache etc.).
Include in Cookie: Add the nonce to the cookie data as an encrypted value.
Verify on Every Request: With every request that uses the cookie, decrypt the nonce and compare it to the one stored on the server for that session. If they don’t match, reject the request.

Example (Python/Flask):

import uuid
from flask import Flask, request, session

def login(username, password):
# … authentication logic…
nonce = str(uuid.uuid4())
session[‘nonce’] = nonce
# Encrypt the nonce before storing in cookie!
encrypted_nonce = encrypt(nonce) # Replace with your encryption function
return encrypted_nonce

def verify_login():
if ‘nonce’ not in session:
return False
cookie_nonce = request.cookies.get(‘my_cookie’) # Get cookie value
decrypted_nonce = decrypt(cookie_nonce) # Replace with your decryption function
if decrypted_nonce != session[‘nonce’]:
return False
return True

Important: Always encrypt the nonce before storing it in a cookie. Never store plain text nonces.

2. IP Address Checking (with Caution)

Record the user’s IP address when they log in and check if subsequent requests come from the same IP. This isn’t foolproof (IP addresses can change), but adds another layer of defence.

Store IP Address: When a user logs in, store their IP address alongside the session data.
Compare on Every Request: With each request, get the current IP address and compare it to the stored one. If they differ significantly, consider rejecting the request or requiring re-authentication.

Example (PHP):

<?php session_start();
if ($_POST['login'] == 'true') {
# … authentication logic…
$_SESSION['ip_address'] = $_SERVER['REMOTE_ADDR'];
}

if ($_SESSION['ip_address'] != $_SERVER['REMOTE_ADDR']) {
// IP address has changed – potential replay attack!
session_destroy();
echo 'Login session invalidated.';
exit;
}

Caution: Don’t rely solely on IP addresses. Users can change IPs (mobile networks, VPNs). Use this as a *supplement* to other methods.

3. Secure Cookie Flags

These flags tell the browser how to handle your cookie:

Secure: Only send the cookie over HTTPS connections. Essential!
HttpOnly: Prevent JavaScript from accessing the cookie, reducing XSS attack risk. Highly recommended!
SameSite: Controls when cookies are sent with cross-site requests. Set to ‘Strict’ or ‘Lax’ for better protection against CSRF attacks. Recommended!

Example (Python/Flask):

from flask import make_response

def set_cookie(value):
resp = make_response(‘Cookie Set’)
resp.set_cookie(‘my_cookie’, value, secure=True, httponly=True, samesite=’Strict’)
return resp

Note: Ensure your entire site uses HTTPS for the ‘Secure’ flag to work effectively.

The post Stop Cookie Replay Attacks appeared first on Blog | G5 Cyber Security.

Categories

No Responses

Leave a Reply

Your email address will not be published. Required fields are marked *