Skip to main content

Starlette CSRF Middleware

Starlette middleware implementing Double Submit Cookie technique to mitigate CSRF.

build codecov PyPI version Downloads

How it works?

  1. The user makes a first request with a method considered safe (by default GET, HEAD, OPTIONS, TRACE).
  2. It receives in response a cookie (named by default csrftoken) which contains a secret value.
  3. When the user wants to make an unsafe request, the server expects them to send the same secret value in a header (named by default x-csrftoken).
  4. The middleware will then compare the secret value provided in the cookie and the header.
    • If they match, the request is processed.
    • Otherwise, a 403 Forbidden error response is given.

This mechanism is necessary if you rely on cookie authentication in a browser. You can have more information about CSRF and Double Submit Cookie in the OWASP Cheat Sheet Series.

Installation

pip install starlette-csrf

Usage with Starlette

from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette_csrf import CSRFMiddleware

routes = ...

middleware = [
    Middleware(CSRFMiddleware, secret="__CHANGE_ME__")
]

app = Starlette(routes=routes, middleware=middleware)

Usage with FastAPI

from fastapi import FastAPI
from starlette_csrf import CSRFMiddleware

app = FastAPI()

app.add_middleware(CSRFMiddleware, secret="__CHANGE_ME__")

Arguments

  • secret (str): Secret to sign the CSRF token value. Be sure to choose a strong passphrase and keep it SECRET.
  • required_urls (Optional[List[re.Pattern]] - None): List of URL regexes that the CSRF check should always be enforced, no matter the method or the cookies present.
  • exempt_urls (Optional[List[re.Pattern]] - None): List of URL regexes that the CSRF check should be skipped on. Useful if you have any APIs that you know do not need CSRF protection.
  • sensitive_cookies (Set[str] - None): Set of cookie names that should trigger the CSRF check if they are present in the request. Useful if you have other authentication methods that don't rely on cookies and don't need CSRF enforcement. If this parameter is None, the default, CSRF is always enforced.
  • safe_methods (Set[str] - {"GET", "HEAD", "OPTIONS", "TRACE"}): HTTP methods considered safe which don't need CSRF protection.
  • cookie_name (str - csrftoken): Name of the cookie.
  • cookie_path str - /): Cookie path.
  • cookie_domain (Optional[str] - None): Cookie domain. If your frontend and API lives in different sub-domains, be sure to set this argument with your root domain to allow your frontend sub-domain to read the cookie on the JavaScript side.
  • cookie_secure (bool - False): Whether to only send the cookie to the server via SSL request.
  • cookie_samesite (str - lax): Samesite strategy of the cookie.
  • header_name (str - x-csrftoken): Name of the header where you should set the CSRF token.

Customize error response

By default, a plain text response with the status code 403 is returned when the CSRF verification is failing. You can customize it by overloading the middleware class and implementing the _get_error_response method. It accepts in argument the original Request object and expects a Response. For example:

from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette_csrf import CSRFMiddleware

class CustomResponseCSRFMiddleware(CSRFMiddleware):
    def _get_error_response(self, request: Request) -> Response:
        return JSONResponse(
            content={"code": "CSRF_ERROR"}, status_code=403
        )

Development

Setup environment

We use Hatch to manage the development environment and production build. Ensure it's installed on your system.

Run unit tests

You can run all the tests with:

hatch run test

Format the code

Execute the following command to apply linting and check typing:

hatch run lint

License

This project is licensed under the terms of the MIT license.

Release files for starlette-csrf 3.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for starlette-csrf 3.0.0
File Size Uploaded
starlette_csrf-3.0.0.tar.gz 8.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for starlette-csrf 3.0.0
File Interpreter ABI Platform
starlette_csrf-3.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 14.5 kB

Release files / starlette_csrf-3.0.0.tar.gz

Download URL starlette_csrf-3.0.0.tar.gz
Size 8.4 kB
Tags Source
SHA-256 checksum
How to use checksums
7afaca8c72cc3c726e5942778af53454607ca3e653fd86cd75ee35d8cd1cfa77
BLAKE2b-256 checksum
How to use checksums
0f7c53c57b4cd76c9a4493a8525d34a76d7e4bbe0ff957de1c53f30241aa757a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.24.1

Release files / starlette_csrf-3.0.0-py3-none-any.whl

Download URL starlette_csrf-3.0.0-py3-none-any.whl
Size 6.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
aac29b366e83621d3fc56be690866e16f3c56df91ab5e184b77950540a4e2761
BLAKE2b-256 checksum
How to use checksums
b9836641e4fdcf33b1cc614a74ecabe5835236a1b2564bf6735db7e35d788795
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-httpx/0.24.1

Release history Release notifications | RSS feed

This release

3.0.0 This release

2 release files

2.0.0

2 release files

1.4.5

2 release files

1.4.4

1 release file

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page