All Projects → simonw → asgi-csrf

simonw / asgi-csrf

Licence: Apache-2.0 license
ASGI middleware for protecting against CSRF attacks

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to asgi-csrf

aioprometheus
A Prometheus Python client library for asyncio-based applications
Stars: ✭ 114 (+165.12%)
Mutual labels:  asgi, asgi-middleware
asgi-ratelimit
A ASGI Middleware to rate limit
Stars: ✭ 170 (+295.35%)
Mutual labels:  asgi, asgi-middleware
Csrf Protector Php
CSRF Protector library: standalone library for CSRF mitigation
Stars: ✭ 178 (+313.95%)
Mutual labels:  csrf
solutions-bwapp
In progress rough solutions to bWAPP / bee-box
Stars: ✭ 158 (+267.44%)
Mutual labels:  csrf
mongox
Familiar async Python MongoDB ODM
Stars: ✭ 113 (+162.79%)
Mutual labels:  asgi
Aura.session
Tools for managing sessions, including session segments and read-once messages
Stars: ✭ 185 (+330.23%)
Mutual labels:  csrf
fastapi-project
FastAPI application without global variables(almost) =)
Stars: ✭ 26 (-39.53%)
Mutual labels:  asgi
Okta Spring Boot React Crud Example
Simple CRUD with React and Spring Boot 2.0
Stars: ✭ 176 (+309.3%)
Mutual labels:  csrf
starlite
Light, Flexible and Extensible ASGI API framework
Stars: ✭ 1,525 (+3446.51%)
Mutual labels:  asgi
fastAPI-aiohttp-example
How to use and test fastAPI with an aiohttp client
Stars: ✭ 69 (+60.47%)
Mutual labels:  asgi
laravel-stateless-session
CSRF verification and session persistent through request/response headers.
Stars: ✭ 33 (-23.26%)
Mutual labels:  csrf
json-head
JSON microservice for performing HEAD requests
Stars: ✭ 31 (-27.91%)
Mutual labels:  asgi
Web Security Fundamentals
👨‍🏫 Mike's Web Security Course
Stars: ✭ 195 (+353.49%)
Mutual labels:  csrf
async-asgi-testclient
A framework-agnostic library for testing ASGI web applications
Stars: ✭ 123 (+186.05%)
Mutual labels:  asgi
Javasecurity
Java web and command line applications demonstrating various security topics
Stars: ✭ 182 (+323.26%)
Mutual labels:  csrf
Spontini
A text-combined-with-graphic music editor for creating professional scores with LilyPond
Stars: ✭ 43 (+0%)
Mutual labels:  asgi
Csurf
CSRF token middleware
Stars: ✭ 2,183 (+4976.74%)
Mutual labels:  csrf
CSRF-tutorial
Use Django To Introduce CSRF and Cookies , Session 📝
Stars: ✭ 49 (+13.95%)
Mutual labels:  csrf
asgi-caches
Server-side HTTP caching for ASGI applications, inspired by Django's cache framework
Stars: ✭ 18 (-58.14%)
Mutual labels:  asgi
Formidable
The PHP pragmatic forms library
Stars: ✭ 116 (+169.77%)
Mutual labels:  csrf

asgi-csrf

PyPI Changelog codecov License

ASGI middleware for protecting against CSRF attacks

Installation

pip install asgi-csrf

Background

See the OWASP guide to Cross Site Request Forgery (CSRF) and their Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet.

This middleware implements the Double Submit Cookie pattern, where a cookie is set that is then compared to a csrftoken hidden form field or a x-csrftoken HTTP header.

Usage

Decorate your ASGI application like this:

from asgi_csrf import asgi_csrf
from .my_asgi_app import app


app = asgi_csrf(app, signing_secret="secret-goes-here")

The middleware will set a csrftoken cookie, if one is missing. The value of that token will be made available to your ASGI application through the scope["csrftoken"] function.

Your application code should include that value as a hidden form field in any POST forms:

<form action="/login" method="POST">
    ...
    <input type="hidden" name="csrftoken" value="{{ request.scope.csrftoken() }}">
</form>

Note that request.scope["csrftoken"]() is a function that returns a string. Calling that function also lets the middleware know that the cookie should be set by that page, if the user does not already have that cookie.

If the cookie needs to be set, the middleware will add a Vary: Cookie header to the response to ensure it is not incorrectly cached by any CDNs or intermediary proxies.

The middleware will return a 403 forbidden error for any POST requests that do not include the matching csrftoken - either in the POST data or in a x-csrftoken HTTP header (useful for JavaScript fetch() calls).

The signing_secret is used to sign the tokens, to protect against subdomain vulnerabilities.

If you do not pass in an explicit signing_secret parameter, the middleware will look for a ASGI_CSRF_SECRET environment variable.

If it cannot find that environment variable, it will generate a random secret which will persist for the lifetime of the server.

This means that if you do not configure a specific secret your user's csrftoken cookies will become invalid every time the server restarts! You should configure a secret.

Always setting the cookie if it is not already set

By default this middleware only sets the csrftoken cookie if the user encounters a page that needs it - due to that page calling the request.scope["csrftoken"]() function, for example to populate a hidden field in a form.

If you would like the middleware to set that cookie for any incoming request that does not already provide the cookie, you can use the always_set_cookie=True argument:

app = asgi_csrf(app, signing_secret="secret-goes-here", always_set_cookie=True)

Other cases that skip CSRF protection

If the request includes an Authorization: Bearer ... header, commonly used by OAuth and JWT authentication, the request will not be required to include a CSRF token. This is because browsers cannot send those headers in a context that can be abused.

If the request has no cookies at all it will be allowed through, since CSRF protection is only necessary for requests from authenticated users.

always_protect

If you have paths that should always be protected even without cookies - your login form for example (to avoid login CSRF attacks) you can protect those paths by passing them as the always_protect parameter:

app = asgi_csrf(
    app,
    signing_secret="secret-goes-here",
    always_protect={"/login"}
)

skip_if_scope

There may be situations in which you want to opt-out of CSRF protection even for authenticated POST requests - this is often the case for web APIs for example.

The skip_if_scope= parameter can be used to provide a callback function which is passed an ASGI scope and returns True if CSRF protection should be skipped for that request.

This example skips CSRF protection for any incoming request where the request path starts with /api/:

def skip_api_paths(scope)
    return scope["path"].startswith("/api/")

app = asgi_csrf(
    app,
    signing_secret="secret-goes-here",
    skip_if_scope=skip_api_paths
)
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].