Skip to main content

How to Configure CSRF Protection

Framework M includes built-in protection against Cross-Site Request Forgery (CSRF). By default, it uses a stateless, origin-based validation model.

Configuring Allowed Origins

The CSRF middleware blocks any state-changing request (POST, PUT, DELETE) where the Origin header does not match your application's domains.

You can configure these origins in your framework_config.toml:

[web.cors]
allowed_origins = [
"https://app.example.com",
"https://billing.example.com",
"http://localhost:3000"
]

Bypassing CSRF for API Clients

CSRF is a browser-specific vulnerability. Clients like cURL, Android apps, or Service-to-Service calls are naturally immune if they are authenticated via headers.

The middleware will automatically bypass validation if:

  1. The request does not include an Origin or Referer header.
  2. AND the request is authenticated via an Authorization or X-API-Key header instead of a session cookie.

Customizing the Validation Logic

If you need a specialized CSRF implementation (e.g., Proof-of-Work headers or Synchronizer Tokens), you can implement the CSRFProtocol.

1. Create a Custom Adapter

from framework_m_standard.interfaces.web import CSRFProtocol, WebRequestInfo

class HeavyDutyCSRFAdapter(CSRFProtocol):
async def validate_request(self, info: WebRequestInfo) -> bool:
# Custom logic here
return True

2. Register the Adapter

Framework M uses entry points to discover security adapters. Add this to your package's pyproject.toml or setup.cfg:

[project.entry-points."framework_m.adapters.csrf"]
my_adapter = "my_app.adapters.security:HeavyDutyCSRFAdapter"

The framework will automatically prefer your custom adapter over the DefaultCSRFAdapter at runtime.


[!IMPORTANT] Always ensure your production allowed_origins matches the exact URI (scheme and port) of your frontend to avoid 403 Forbidden errors.