
SPA Token Flow and Attack Vector
Modern SPAs (Single Page Applications) feel seamless. You click around, and things just happen. No reloads. No waiting. Smooth UX.
But under that smoothness, session management often takes a hit. And when it’s not done right, it opens the door to one of the oldest attacks in the book: session hijacking.
Let’s break down what that means, how it happens, and how the backend can actually prevent it.
What Is Session Hijacking?
Session hijacking is when an attacker takes over a user’s session and pretends to be them.
Once they’re in, they can:
- Access sensitive data
- Interact with APIs as the user
- Make changes to the account
- Essentially become that user
This can happen in any web app, but SPAs introduce specific risks that make it easier to get wrong.
Why SPAs Make This Risk Worse
SPAs usually rely on tokens like JWTs to manage authentication and session state. These tokens are often stored in:
localStoragesessionStorage- In-memory variables
Storing tokens in the browser like this can be dangerous. If an attacker finds a way to run JavaScript inside your app (through something like XSS), they can grab the token and send it to themselves. Once they have the token, they can use it to impersonate the user.
This risk is real, and it’s common.
Common Ways Sessions Get Hijacked
1. XSS (Cross-Site Scripting)
If your app allows an attacker to inject JavaScript, they can access whatever is in storage. That includes your auth tokens.
2. Insecure Cookies
If you do use cookies but forget to set the right flags, you’re leaving the session exposed. Cookies need to be HttpOnly, Secure, and SameSite to reduce the risk.
3. Token Leakage
Tokens in URLs, browser history, logs, or error messages are easy to miss. But if they leak, anyone with access can use them.
4. Man-in-the-Middle (MITM)
If your app is not using HTTPS everywhere, someone on the same network can intercept traffic and steal tokens or cookies.
What the Backend Can Actually Do
A lot of developers think session safety is a frontend concern in SPAs. It’s not. The backend still controls the logic that makes or breaks security.
Here’s what your backend should be doing.
1. Use Secure, HttpOnly Cookies
Store your access tokens in cookies, not in localStorage. Use the following flags:
HttpOnly: prevents JavaScript from accessing the cookieSecure: only sends cookies over HTTPSSameSite: helps prevent CSRF attacks
This setup blocks the most common attacks by keeping tokens out of reach from JavaScript.
2. Rotate and Revoke Tokens
Make sure your tokens do not live forever.
- Short lifespans for access tokens
- Rotate refresh tokens on each use
- Revoke tokens on logout or suspicious activity
This limits the time window an attacker has, even if they manage to steal something.
3. Bind Sessions to Client Context
Sessions should be tied to client properties. For example:
- IP address (with tolerance for changes)
- User-agent or device fingerprint
- Geolocation
If a request suddenly comes from a very different context, invalidate the session and ask the user to log in again.
4. Monitor Behavior on the Server Side
The backend can track behavior and spot anomalies:
- Multiple logins from different countries
- Unusual API patterns
- Sudden spikes in requests
Once detected, take action. Block the session, force logout, notify the user.
5. Invalidate on Critical Changes
If the user changes their password, adds a new device, or completes MFA, terminate existing sessions.
Never assume older sessions are safe after sensitive account changes.
Summary: You Cannot Trust the Frontend Alone
SPAs give users a great experience. But they also move a lot of logic and session handling into the browser, which is a risky place.
The frontend cannot be your source of truth. The backend must handle:
- Session issuance
- Session verification
- Context validation
- Token rotation and revocation
Do not rely on storage mechanisms in the browser to keep your users safe. Build your security model on the server side, where you have control.
Final Thoughts
SPAs are fast. But attackers are faster if your session management is weak.
Security doesn’t come from using the latest frameworks or copying example code from blog posts. It comes from understanding how sessions work, how they get stolen, and how to lock them down.
Assume nothing. Check everything. Build your security where it matters — on the backend.