Nitan Jana

Jan 15, 2026 • 2 min read

What is a CSRF Attack?

Cross-Site Request Forgery (CSRF) is an attack where a user is tricked into unknowingly performing actions on a web application they are already logged into. Because the user is authenticated, the application treats the forged request as legitimate, even though the user never intended to perform it.

Attack Pattern:

1. A user is logged into your app (for example, myapp.com) using their email/password account

2. An attacker obtains a valid OAuth authorization code issued to their own LinkedIn account for your app

3. The attacker creates a malicious page (for example, on attacker.com) containing something like:
<img src="https[:]//myapp[.]com/api/linkedin/callback?code=ATTACKER_CODE&state=ATTACKER_STATE" width="0" height="0">

4. The attacker tricks the victim into visiting attacker[.]com while the victim is still logged into myapp.com

5. The victim’s browser automatically sends the request to your app, including the victim’s session cookie

6. If your app does not validate the OAuth state, it processes the callback and links the attacker’s LinkedIn account to the victim’s app account

7. The victim’s account is now connected to the attacker’s LinkedIn profile


Why This Is Dangerous:

- If your app supports “Login with LinkedIn”, the attacker can later log in using their LinkedIn account and gain full access to the victim’s app account without knowing the victim’s password.

- OAuth account linking is usually persistent. Once the attacker’s LinkedIn account is linked, access remains until the victim notices and removes it, which often does not happen.

- This bypasses password-based protections such as password changes or MFA, since OAuth becomes an alternative login method.

- The application mistakenly treats OAuth callbacks as proof of user intent, allowing attackers to complete authentication flows on behalf of other users.


How We Protected Our OAuth Flow from CSRF at SuperImpress:


- A cryptographically secure random state token is generated for each OAuth authorization request

- The backend stores the token in Redis with a 10-minute TTL

- The state value is passed through the entire OAuth flow and validated at multiple stages

- The frontend stores the state in sessionStorage before redirecting and validates it on callback

- The backend performs a second verification against Redis and deletes the token after use so it can only be used once

- Redis ensures tokens expire automatically and cannot be reused

- Frontend and backend validation together provide defense-in-depth against CSRF attacks

Ref PRs:
https://github.com/yaralahruthik/super-impress/pull/85
https://github.com/yaralahruthik/super-impress/pull/97

A good article by Auth0 on this: https://auth0.com/docs/secure/attack-protection/state-parameters

Join Nitan on Peerlist!

Join amazing folks like Nitan and thousands of other builders on Peerlist.

peerlist.io/

It’s available... this username is available! 😃

Claim your username before it's too late!

This username is already taken, you’re a little late.😐

0

0

0