{"id":6005,"date":"2025-11-29T02:26:51","date_gmt":"2025-11-29T02:26:51","guid":{"rendered":"https:\/\/cybersecurityinfocus.com\/?p=6005"},"modified":"2025-11-29T02:26:51","modified_gmt":"2025-11-29T02:26:51","slug":"stop-cookie-replay-attacks","status":"publish","type":"post","link":"https:\/\/cybersecurityinfocus.com\/?p=6005","title":{"rendered":"Stop Cookie Replay Attacks"},"content":{"rendered":"<h2>TL;DR<\/h2>\n<p>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 \u2013 using a unique \u2018nonce\u2019 (number used once) with each login, checking the user\u2019s IP address, and setting secure flags on cookies \u2013 to make these attacks much harder.<\/p>\n<h2>How Replay Attacks Work<\/h2>\n<p>Imagine you log into your bank. Your browser gets a cookie that proves you\u2019re logged in. If someone steals this cookie, they can use it to access your account without needing your password. That\u2019s a replay attack. We need ways to make sure the cookie isn\u2019t used after it *should* be.<\/p>\n<h2>Solution: Layered Security<\/h2>\n<p>We\u2019ll combine three techniques for better protection:<\/p>\n<p>Unique Nonce per Login<br \/>\nIP Address Checking (with caution)<br \/>\nSecure Cookie Flags<\/p>\n<h2>1. Unique Nonce per Login<\/h2>\n<p>A nonce is a random, unique number generated for each login session. We store this on the server and check it with every request.<\/p>\n<p>Generate the Nonce: When a user logs in successfully, create a strong random string (e.g., using a UUID).<br \/>\nStore the Nonce: Save this nonce associated with the user\u2019s session on your server-side storage (database, cache etc.).<br \/>\nInclude in Cookie: Add the nonce to the cookie data as an encrypted value.<br \/>\nVerify 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\u2019t match, reject the request.<\/p>\n<p>Example (Python\/Flask):<\/p>\n<p>import uuid<br \/>\nfrom flask import Flask, request, session<\/p>\n<p>def login(username, password):<br \/>\n  # &#8230; authentication logic&#8230;<br \/>\n  nonce = str(uuid.uuid4())<br \/>\n  session[&#8216;nonce&#8217;] = nonce<br \/>\n  # Encrypt the nonce before storing in cookie!<br \/>\n  encrypted_nonce = encrypt(nonce) # Replace with your encryption function<br \/>\n  return encrypted_nonce<\/p>\n<p>def verify_login():<br \/>\n  if &#8216;nonce&#8217; not in session:<br \/>\n    return False<br \/>\n  cookie_nonce = request.cookies.get(&#8216;my_cookie&#8217;) # Get cookie value<br \/>\n  decrypted_nonce = decrypt(cookie_nonce) # Replace with your decryption function<br \/>\n  if decrypted_nonce != session[&#8216;nonce&#8217;]:<br \/>\n    return False<br \/>\n  return True<\/p>\n<p>Important: Always encrypt the nonce before storing it in a cookie. Never store plain text nonces.<\/p>\n<h2>2. IP Address Checking (with Caution)<\/h2>\n<p>Record the user\u2019s IP address when they log in and check if subsequent requests come from the same IP.  This isn\u2019t foolproof (IP addresses can change), but adds another layer of defence.<\/p>\n<p>Store IP Address: When a user logs in, store their IP address alongside the session data.<br \/>\nCompare 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.<\/p>\n<p>Example (PHP):<\/p>\n<p>&lt;?php session_start();<br \/>\nif ($_POST[&#039;login&#039;] == &#039;true&#039;) {<br \/>\n  # &#8230; authentication logic&#8230;<br \/>\n  $_SESSION[&#039;ip_address&#039;] = $_SERVER[&#039;REMOTE_ADDR&#039;];<br \/>\n}<\/p>\n<p>if ($_SESSION[&#039;ip_address&#039;] != $_SERVER[&#039;REMOTE_ADDR&#039;]) {<br \/>\n  \/\/ IP address has changed &#8211; potential replay attack!<br \/>\n  session_destroy();<br \/>\n  echo &#039;Login session invalidated.&#039;;<br \/>\n  exit;<br \/>\n}<\/p>\n<p>Caution: Don&#8217;t rely solely on IP addresses. Users can change IPs (mobile networks, VPNs). Use this as a *supplement* to other methods.<\/p>\n<h2>3. Secure Cookie Flags<\/h2>\n<p>These flags tell the browser how to handle your cookie:<\/p>\n<p>Secure: Only send the cookie over HTTPS connections. Essential!<br \/>\nHttpOnly: Prevent JavaScript from accessing the cookie, reducing XSS attack risk. Highly recommended!<br \/>\nSameSite: Controls when cookies are sent with cross-site requests. Set to &#8216;Strict&#8217; or &#8216;Lax&#8217; for better protection against CSRF attacks. Recommended!<\/p>\n<p>Example (Python\/Flask):<\/p>\n<p>from flask import make_response<\/p>\n<p>def set_cookie(value):<br \/>\n  resp = make_response(&#8216;Cookie Set&#8217;)<br \/>\n  resp.set_cookie(&#8216;my_cookie&#8217;, value, secure=True, httponly=True, samesite=&#8217;Strict&#8217;)<br \/>\n  return resp<\/p>\n<p>Note: Ensure your entire site uses HTTPS for the &#8216;Secure&#8217; flag to work effectively.<\/p>\n<p>The post <a href=\"https:\/\/blog.g5cybersecurity.com\/stop-cookie-replay-attacks\/\">Stop Cookie Replay Attacks<\/a> appeared first on <a href=\"https:\/\/blog.g5cybersecurity.com\/\">Blog | G5 Cyber Security<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>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 \u2013 using a unique \u2018nonce\u2019 (number used once) with each login, checking the user\u2019s IP address, and setting secure flags on cookies \u2013 to make these attacks much [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6005","post","type-post","status-publish","format-standard","hentry","category-news"],"_links":{"self":[{"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=\/wp\/v2\/posts\/6005"}],"collection":[{"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6005"}],"version-history":[{"count":0,"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=\/wp\/v2\/posts\/6005\/revisions"}],"wp:attachment":[{"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6005"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6005"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cybersecurityinfocus.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}