All vulnerabilities
MediumA01:2021CWE-352Broken Access Control

Cross-Site Request Forgery (CSRF)

CSRF tricks authenticated users into unknowingly submitting requests to your application — changing their email, transferring funds, or deleting their account — from a malicious third-party site.

What Is CSRF?

Cross-Site Request Forgery (CSRF) abuses the fact that browsers automatically send cookies with every request to a domain. An attacker can craft a page that submits a form or makes a fetch request to your app — and if the victim is logged in, their session cookie is included automatically.

How It Works

Your app has an endpoint to change a user's email:

POST /api/account/email
Cookie: session=abc123
Body: email=new@email.com

The attacker creates a malicious page:

<!-- evil.com — auto-submits on page load -->
<form action="https://yourapp.com/api/account/email" method="POST" id="f">
  <input name="email" value="attacker@evil.com">
</form>
<script>document.getElementById('f').submit()</script>

When a logged-in victim visits evil.com, their browser sends the POST with their session cookie. The attacker now controls the account email and can request a password reset.

Real-World Impact

  • Account takeover — change email/password without the user's knowledge
  • Financial fraud — trigger transfers, purchases, or subscription changes
  • Data destruction — delete user data or content
  • Privilege changes — if admin actions lack CSRF protection, grant attacker admin access

How to Fix

Use SameSite cookies (most effective modern defense):

# Set cookies with SameSite=Strict or Lax
response.set_cookie(
    "session",
    value=session_token,
    httponly=True,
    secure=True,
    samesite="lax",  # Blocks cross-site POST requests
)

SameSite=Strict blocks all cross-origin requests; SameSite=Lax blocks cross-origin POST but allows top-level navigation.

CSRF tokens for forms:

import secrets
 
# Generate per-session token
csrf_token = secrets.token_hex(32)
session["csrf_token"] = csrf_token
 
# Validate on state-changing requests
def verify_csrf(request):
    token = request.form.get("csrf_token") or request.headers.get("X-CSRF-Token")
    if not secrets.compare_digest(token or "", session.get("csrf_token", "")):
        raise HTTPException(403, "CSRF validation failed")

Verify Origin/Referer header as a secondary check:

origin = request.headers.get("origin")
if origin and origin not in ALLOWED_ORIGINS:
    raise HTTPException(403, "Forbidden")

What VibeWShield Detects

VibeWShield checks whether state-changing endpoints (POST, PUT, DELETE, PATCH) lack CSRF token validation and whether session cookies are set without SameSite attribute. It also tests for missing Origin header verification on sensitive endpoints.

#csrf#authentication#forms#cookies

Free security scan

Test your app for Cross-Site Request Forgery (CSRF)

VibeWShield automatically checks for Cross-Site Request Forgery (CSRF) and 40+ other vulnerabilities using 63 scanners — in under 3 minutes, no signup required.

Scan your app free