microdot.csrf — CSRF-Schutz

Lehnt zustandsändernde Anfragen ab, die von einer anderen Website stammen. Die Prüfung läuft als before_request-Hook und verwendet den vom Browser gelieferten Sec-Fetch-Site-Header (mit dem Origin-Header als Rückfalloption für ältere Browser, sofern mit einer microdot.cors.CORS-Instanz kombiniert).

class CSRF

class microdot.csrf.CSRF(app: Microdot | None = None, cors=None, protect_all: bool = True, allow_subdomains: bool = False)
app

Die microdot.Microdot-Instanz, auf der installiert werden soll. Optional; rufe später initialize() auf, falls nicht angegeben.

cors

Die microdot.cors.CORS-Instanz, die die vertrauenswürdigen Origins der Anwendung definiert. Erforderlich für den Rückfall auf den Origin-Header bei Browsern, die Sec-Fetch-Site nicht senden. Optional; ohne sie gilt nur die Sec-Fetch-Site-Prüfung.

protect_all

Wenn True (Standard), wird jede Route außer GET, HEAD und OPTIONS automatisch geschützt. Einzelne Routen können mit exempt() ausgenommen werden. Wenn False, werden standardmäßig keine Routen geschützt und einzelne Routen melden sich mit protect() an.

allow_subdomains

Wenn True, werden Anfragen von Subdomains der Origins der Anwendung akzeptiert (same-site Sec-Fetch-Site oder übereinstimmendes Origin-Suffix).

initialize(app: Microdot, cors=None)

An app anbinden, falls die Konstruktion aufgeschoben wurde.

exempt(f)

Dekorator, der eine Route vom CSRF-Schutz ausnimmt. Platziere ihn direkt nach dem Routen-Dekorator:

@app.post('/webhook')
@csrf.exempt
async def webhook(request):
    # accepts cross-site POSTs
protect(f)

Dekorator, der den CSRF-Schutz für eine Route erzwingt, die andernfalls ausgenommen wäre (z. B. eine GET-Route oder jede Route bei protect_all=False).

SAFE_METHODS: list

Klassenattribut, das die standardmäßig nicht geschützten Methoden auflistet – ['GET', 'HEAD', 'OPTIONS'].

Beispiel:

from microdot import Microdot
from microdot.cors import CORS
from microdot.csrf import CSRF

app = Microdot()
cors = CORS(app, allowed_origins=['https://app.example.com'])
csrf = CSRF(app, cors=cors)

@app.post('/api/save')
async def save(request):
    # automatically CSRF-protected
    return {'ok': True}

Eine Anfrage wird zugelassen, wenn Sec-Fetch-Site same-origin oder none meldet (oder same-site, wenn allow_subdomains=True). Fehlt der Header, wird der Origin der Anfrage gegen die CORS-Erlaubnisliste abgeglichen. Anfragen ohne einen der beiden Header werden akzeptiert (typisch für direkte API-Aufrufe, die nicht dem Browser-CSRF unterliegen).