microdot.csrf — ochrona CSRF

Odrzuca żądania zmieniające stan, które pochodzą z innej witryny. Sprawdzenie działa jako punkt zaczepienia before_request i wykorzystuje dostarczony przez przeglądarkę nagłówek Sec-Fetch-Site (z nagłówkiem Origin jako rozwiązaniem awaryjnym dla starszych przeglądarek, gdy jest sparowane z instancją microdot.cors.CORS).

class CSRF

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

Instancja microdot.Microdot, w której należy zainstalować. Opcjonalna; wywołaj initialize() później, jeśli nie zostanie podana.

cors

Instancja microdot.cors.CORS, która definiuje zaufane źródła aplikacji. Wymagana do skorzystania z rozwiązania awaryjnego opartego na nagłówku Origin w przeglądarkach, które nie wysyłają Sec-Fetch-Site. Opcjonalna; bez niej stosowane jest tylko sprawdzanie Sec-Fetch-Site.

protect_all

Jeśli True (domyślnie), każda trasa z wyjątkiem GET, HEAD i OPTIONS jest chroniona automatycznie. Trasy można indywidualnie zwolnić za pomocą exempt(). Jeśli False, żadne trasy nie są domyślnie chronione, a poszczególne trasy włączają ochronę za pomocą protect().

allow_subdomains

Jeśli True, żądania z subdomen źródeł aplikacji są akceptowane (same-site Sec-Fetch-Site lub pasujący sufiks źródła).

initialize(app: Microdot, cors=None)

Podłącza do app, jeśli konstrukcja została odroczona.

exempt(f)

Dekorator zwalniający trasę z ochrony CSRF. Umieść go bezpośrednio po dekoratorze trasy:

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

Dekorator wymuszający ochronę CSRF na trasie, która w przeciwnym razie byłaby zwolniona (np. trasa GET lub każda trasa, gdy protect_all=False).

SAFE_METHODS: list

Atrybut klasy wymieniający metody, które domyślnie nie są chronione – ['GET', 'HEAD', 'OPTIONS'].

Przykład:

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}

Żądanie jest dozwolone, gdy Sec-Fetch-Site zgłasza same-origin lub none (lub same-site, gdy allow_subdomains=True). Jeśli nagłówek jest nieobecny, Origin żądania jest dopasowywany do listy dozwolonych CORS. Żądania bez żadnego z tych nagłówków są akceptowane (typowe dla bezpośrednich wywołań API, które nie podlegają CSRF przeglądarki).