Why MFA Can’t Stop Token Theft: Inside the Rise of Session Hijacking—and How DPoP Helps

Dileep Solanki

 



For years, whenever I thought about account security, MFA was one of the first things I recommended.

Use an authenticator app.
Use a hardware security key.
Use a passkey.

Those protections are still extremely important.

But there is a problem I think developers sometimes overlook: MFA protects the authentication event. It doesn't automatically protect everything that happens after authentication.

Once I successfully sign in, my browser receives some form of authenticated session state. Depending on the application, that might involve cookies, OAuth access tokens, refresh tokens, or other credentials.

If an attacker manages to steal that authenticated state, they may not need my password or MFA factor again.

That's why session and token theft deserve much more attention.

In this article, I'll walk through how token theft can bypass the authentication step, why traditional bearer tokens create a replay problem, and how DPoP (Demonstrating Proof-of-Possession) can reduce that risk by binding tokens to a cryptographic key.


1. How Session Hijacking Can Bypass MFA

The easiest way for me to understand this problem is to separate authentication from session use.

When I log into a modern web application, the process generally looks something like this:

[My Device]
     │
     │ Password + MFA / Passkey
     ▼
[Identity Provider]
     │
     │ Authenticated Session
     ▼
[Browser]
     │
     │ Session Cookie / Access Token
     ▼
[Application]

The important point is what happens after authentication.

I might successfully complete MFA once, and the application then gives my browser an authenticated session.

My browser uses that session for subsequent requests.

If an attacker obtains a credential that can be replayed as a bearer credential, the attacker may be able to use it without completing the original MFA challenge again.

That's fundamentally different from guessing my password.


What Does “Bearer” Actually Mean?

The word bearer is important.

A bearer credential essentially means that possession of the credential is what gives the holder the ability to use it.

A simplified example looks like this:

GET /api/account HTTP/1.1
Host: api.example.com
Authorization: Bearer <access-token>

The server validates the token and, assuming everything else is acceptable, processes the request.

The server doesn't necessarily know that the person presenting the token is the same person who originally completed MFA.

That's why stealing an active credential can be so valuable to an attacker.


2. How Infostealers Target Session Data

One threat category I pay particular attention to here is infostealer malware.

These programs are designed to collect information from compromised devices, potentially including browser-stored credentials and session information.

The general attack chain can look like this:

[Compromised Device]
        │
        ▼
[Infostealer]
        │
        ├── Browser Data
        ├── Cookies
        ├── Credentials
        └── Other Session Information
        │
        ▼
[Attacker Infrastructure]
        │
        ▼
[Attempted Session Replay]

The important distinction is that the attacker isn't necessarily trying to break the authentication system.

They're trying to obtain something that was already authenticated.


3. Why Browser Session Theft Is Dangerous

Modern browsers maintain a considerable amount of local application state.

Depending on the browser and application, that can include cookies and other authentication-related information.

An infostealer may attempt to locate this information on the compromised machine.

The exact storage mechanisms and protections differ between browsers and operating systems, so I wouldn't treat a single browser-storage path as representative of every environment.

The defensive takeaway is more important:

Protecting passwords isn't enough if an attacker can compromise the endpoint and obtain reusable authenticated session material.

This is also why endpoint security matters even when an organization has strong identity controls.


4. Where MFA Still Helps

I wouldn't interpret token theft as meaning MFA is useless.

Quite the opposite.

MFA remains an important defense against:

  • Password theft
  • Credential stuffing
  • Password reuse
  • Many phishing attacks
  • Unauthorized login attempts

The problem is that MFA generally happens during authentication.

Once the session has already been established, the security problem changes.

So I think about the defenses in layers:

Password / Passkey
        ↓
MFA / Strong Authentication
        ↓
Session Security
        ↓
Token Protection
        ↓
Endpoint Security
        ↓
Continuous Monitoring

Each layer addresses a different part of the attack surface.


5. The Structural Idea Behind DPoP

This is where DPoP, defined by RFC 9449, becomes interesting.

DPoP stands for:

Demonstrating Proof-of-Possession

The idea is to make an access token more difficult to use if somebody simply copies it.

Traditional bearer-token authentication effectively says:

“If you possess this token, you can present it.”

DPoP adds another requirement:

“You must also prove possession of the private key associated with this token.”

That changes the security model.


6. How DPoP Works

At a simplified level, I can think of the process like this.

Step 1: Generate a Key Pair

The client generates an asymmetric key pair:

Private Key
     +
Public Key

The private key must remain protected by the client.

Step 2: Bind the Token to the Key

The authorization server associates the access token with the client's public key.

Now the token isn't simply a standalone bearer credential.

It is associated with a particular key.

Step 3: Create a DPoP Proof

When the client makes an API request, it creates a signed DPoP proof.

The proof contains information about the request, including things such as:

  • HTTP method
  • Target URI
  • Unique identifier
  • Timestamp
  • Other protocol-required claims

Step 4: Sign the Proof

The client signs the proof using the private key.

Conceptually:

HTTP Request
     │
     ├── Access Token
     │
     └── DPoP Proof
             │
             ▼
       Signed with
       Private Key

Step 5: Server Verification

The server verifies the proof and checks that it corresponds to the key associated with the access token.

If the attacker only has the token but doesn't possess the corresponding private key, the attacker cannot simply replay the credential in the same way.


7. Why DPoP Changes the Token-Theft Problem

This is the part I find most interesting.

Imagine an attacker manages to steal a token.

With a conventional bearer credential, the attacker may be able to attempt replaying that token from another system.

With DPoP, the attacker also needs the corresponding private key and must generate valid proofs for requests.

So:

Bearer Token
Stolen Token
│
▼
Attacker
│
▼
Replay Attempt

versus:

DPoP
Stolen Access Token
│
▼
Attacker
│
├── Missing Private Key
│
▼
Invalid Proof
│
▼
Request Rejected

That doesn't make endpoint compromise harmless.

If malware compromises the actual client environment and gains access to the private key or can operate through the legitimate client, DPoP isn't a magical solution.

What DPoP does is make simple token copying and replay substantially harder.

That's an important distinction.


8. DPoP Is Not a Replacement for Endpoint Security

I would not deploy DPoP and then consider the token-theft problem solved.

There are still several things I need to protect:

  • The endpoint
  • The private key
  • Browser sessions
  • Application credentials
  • Refresh tokens
  • APIs
  • Identity infrastructure

DPoP is one layer in the architecture.

It is particularly useful because it changes a token from a broadly replayable bearer credential into a credential that requires proof of possession of a cryptographic key.


9. What Developers Can Do Today

If I'm designing an authentication system, I would approach token protection in several layers.

1. Consider Sender-Constrained Tokens

If my OAuth architecture and identity provider support DPoP, I would evaluate whether sender-constrained access tokens make sense for my application.

The important first step is checking the current capabilities of the identity provider and OAuth libraries I'm actually using.


2. Protect Session Cookies

For browser applications, I would use appropriate cookie security attributes.

For example:

Set-Cookie: session=<value>;
HttpOnly;
Secure;
SameSite=Strict

The exact SameSite setting depends on the application's architecture.

The important principles are:

  • Secure helps ensure the cookie is sent only over HTTPS.
  • HttpOnly prevents normal client-side JavaScript from directly reading the cookie.
  • SameSite can reduce certain cross-site request risks.

These controls don't make an endpoint compromise harmless, but they reduce common attack paths.


10. Be Careful With localStorage

I would also avoid casually putting long-lived sensitive credentials into browser localStorage.

One reason is straightforward:

JavaScript running in the application's origin can access localStorage.

So if I have an XSS vulnerability, an attacker may potentially be able to access sensitive values stored there.

That doesn't mean every application using localStorage is automatically vulnerable.

It means I need to understand exactly what I'm storing there and what happens if client-side JavaScript is compromised.

For browser sessions, properly configured HttpOnly cookies are often a better fit for sensitive session credentials.


11. Consider Device-Bound Credentials

Another direction I would watch is device-bound session credentials.

The broader idea is similar to DPoP:

Don't make authentication state freely exportable.

Instead, bind the session to a cryptographic key associated with the device.

This can make stolen browser database files less useful to an attacker because copying the raw data isn't necessarily enough to reproduce a valid authenticated session.

The exact browser and platform support varies, so I would verify current implementation details before designing around it.


12. Add Continuous Monitoring

Token protection shouldn't be the only defense.

I would also monitor for suspicious authentication behavior.

For example:

  • Unexpected geographic changes
  • Unusual device characteristics
  • Abnormal API usage
  • Impossible travel patterns
  • Sudden changes in access behavior
  • Compromised endpoint signals

If my identity infrastructure supports continuous risk evaluation or security-event signaling, I can use those capabilities to respond to suspicious sessions more quickly.

The goal is to reduce the amount of time an attacker can use a compromised session.


13. Protect the Endpoint Too

This is probably the most obvious point, but it is also one of the easiest to overlook.

If malware has full control over my workstation, I have a much bigger problem than one stolen cookie.

An attacker may potentially:

  • Read files
  • Observe application activity
  • Access credentials
  • Modify software
  • Intercept requests
  • Abuse legitimate sessions

So I still need strong endpoint security:

  • Keep operating systems updated
  • Use reputable endpoint protection
  • Restrict administrator privileges
  • Be careful with unknown software
  • Review browser extensions
  • Avoid untrusted developer packages
  • Monitor suspicious processes
  • Protect secrets appropriately

Token-binding technologies complement endpoint security.

They don't replace it.


The Architecture I Would Aim For

If I were designing a modern application, I would think about authentication like this:

                 ┌──────────────────────┐
                 │ Strong Authentication│
                 │ MFA / Passkeys       │
                 └──────────┬───────────┘
                            │
                            ▼
                 ┌──────────────────────┐
                 │ Secure Session       │
                 │ Cookies / Tokens     │
                 └──────────┬───────────┘
                            │
                            ▼
                 ┌──────────────────────┐
                 │ Sender Constraint    │
                 │ DPoP / Device Bound  │
                 └──────────┬───────────┘
                            │
                            ▼
                 ┌──────────────────────┐
                 │ Continuous Monitoring│
                 │ & Risk Detection     │
                 └──────────┬───────────┘
                            │
                            ▼
                 ┌──────────────────────┐
                 │ Protected Endpoint  │
                 └──────────────────────┘

I don't think there is one technology that solves session hijacking.

I think the better approach is to make every layer harder to bypass.


Final Thoughts

The lesson I take from token theft isn't that MFA has failed.

It's that authentication and session security are two different problems.

MFA can make it much harder for an attacker to authenticate as me in the first place.

But if an attacker compromises my device and obtains a reusable authentication credential, the attacker may try to bypass that authentication step entirely.

That's why I'm interested in sender-constrained authentication.

DPoP changes the question from:

“Whoever has the token can use it.”

to something closer to:

“Whoever has the token must also prove possession of the associated private key.”

That is a meaningful architectural improvement for applications that can support it.

But I wouldn't stop there.

I would combine strong authentication, secure cookies, endpoint protection, token lifetime controls, monitoring, and—where appropriate—sender-constrained tokens such as DPoP.

The future of authentication isn't just about making the front door harder to break.

It's also about making stolen authentication material much harder to reuse.

3/related/default