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:
- The request does not include an
OriginorRefererheader. - AND the request is authenticated via an
AuthorizationorX-API-Keyheader 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_originsmatches the exact URI (scheme and port) of your frontend to avoid403 Forbiddenerrors.