
Session Hijacking Starts With Your Cookies — Here's What You Missed
Most developers think session hijacking is an advanced attack. It's not. It usually starts with something very basic: your cookies. Learn the 3 flags and token refresh pattern that actually works.
Most developers think session hijacking is some "advanced hacker attack".
It's not.
It usually starts with something very basic: your cookiesyour cookies
A Small Mistake That Becomes a Big Problem
A real situation I've seen:
- App was using JWT stored in cookies
- Everything worked fine in dev and staging
- Deployed to production
- But:
👉 Cookies were not marked Secure
👉 Someone on the same network intercepted traffic
👉 Session got reused
No password needed. No brute force. Just cookie reuse.
🤔 Why Cookies Matter More Than You Think
When you log in:
- Server gives you a session or token
- Browser stores it (usually in cookies)
- Every request automatically includes it
👉 That cookie is your identityThat cookie is your identity
If someone gets it → they are you.
How Session Hijacking Actually Happens

Common real-world paths:
1. Network Interception (HTTP / insecure setups)
- Using public WiFi
- Traffic not encrypted properly
- Cookies sent in plain text
2. XSS (Cross-Site Scripting)
document.cookieIf your cookie is readable → attacker can steal it.
3. CSRF (Cross-Site Request Forgery)
Browser automatically sends cookies:
👉 Even when request is triggered from another site
4. Token Leakage (logs / frontend)
- Logging tokens accidentally
- Exposing via frontend (localStorage, window)
The Problem Most JWT Articles Don't Explain
Everyone talks about:
- "Use JWT"
- "Store token"
- "Use refresh token"
But they don't tell you:
👉 Where you store the token matters more than the token itselfWhere you store the token matters more than the token itself
🔐 The 3 Cookie Flags You Should NEVER Ignore

1. HttpOnly — Protect Against XSS
What it does:
👉 Prevents JavaScript from accessing cookies
Set-Cookie: token=abc123; HttpOnlyWhy it matters:
Even if XSS exists:
document.cookie // ❌ cannot access HttpOnly cookies2. Secure — Only Over HTTPS

What it does:
👉 Cookie is sent ONLY over HTTPS
Set-Cookie: token=abc123; SecureWhy it matters:
- Prevents MITM attacks
- Protects on public networks
3. SameSite — Protection Against CSRF

Options:
SameSite=Strict // safest
SameSite=Lax // balanced
SameSite=None // required for cross-domain (must use Secure)Why it matters:
👉 Prevents browser from sending cookies in cross-site requests
What a Secure Cookie Setup Actually Looks Like
Set-Cookie: accessToken=xyz;
HttpOnly;
Secure;
SameSite=Strict;
Path=/;👉 This should be your default baseline
🔄 Token Refresh Pattern (Where Most Apps Fail)
Many apps do this wrong:
❌ Store long-lived JWT in browser
❌ No refresh logic
❌ Token valid for days✅ Correct Pattern
Access Token
- Short-lived (5–15 min)
- Stored in HttpOnly cookie
Refresh Token
- Longer-lived
- Stored securely (also HttpOnly cookie)
Flow:
- User logs in
- Server sends:
- accessToken (short life)
- refreshToken (long life)
- Server sends:
- When access token expires:
- frontend calls /refresh
- server verifies refresh token
- issues new access token
👉 Even if access token leaks → damage is limited
Common Mistakes (I See This A LOT)
❌ Storing JWT in localStorage
localStorage.setItem("token", token);👉 Easily accessible via XSS
❌ Missing Secure flag in production
👉 Works in dev → breaks security in prod
❌ Using SameSite=None without Secure
👉 Browser may reject or expose cookie
❌ Logging tokens
console.log(req.headers.authorization);👉 Logs = permanent leak
❌ Sharing tokens across subdomains without isolation
👉 One compromised app = all sessions compromised
How This Connects To Your Previous JWT Article
Your JWT article likely covered:

- Token generation
- Signing
- Validation
This article completes it:
👉 Storage + transport securityStorage + transport security
Because:
A perfectly signed JWT is useless if it's stolen.
Practical Setup (Based on Your Stack)
You are using:
- Next.js
- Node.js
- Backend (Node.js / Express)
Express setup:
res.cookie("accessToken", token, {
httpOnly: true,
secure: true,
sameSite: "strict",
});Next.js (API routes)
Use cookies, NOT localStorage.
Docker / NGINX
👉 Ensure HTTPS termination is correct
👉 Otherwise Secure flag won't work properly
Final Thought
Most developers secure:
- Passwords
- APIs
- Database
But forget:
👉 the thing that represents the user session
And that's the easiest entry point.
🚀 What You Should Do Today
- Check your cookies in DevTools
- Verify flags:
- HttpOnly ✅
- Secure ✅
- SameSite ✅
- Remove tokens from localStorage
- Implement refresh token flow
Enjoying this article?
Get new articles, tips, and fixes delivered straight to your inbox — free, no spam.
Was this article helpful?
Let me know if this was useful — it helps me write more content like this.
Related Articles
You might also enjoy these
CORS Isn't a Bug - It's Your API Trying to Warn You (And You Ignored It)
Stop fighting CORS. Understand preflight requests, credentials, wildcard mistakes. CORS isn't a bug—it's your API warning you about real security issues.
ESM vs CJS — Why Your import Still Breaks in 2026 and How to Finally Fix It
ERR_REQUIRE_ESM. Missing extensions. No __dirname. The ESM/CJS war is still breaking Node.js projects in 2026. Here's the root cause, all five errors you'll hit, and the exact fixes for each one.


Comments
Leave a Comment
All comments are reviewed before publishing