microdot.csrf — CSRF-bescherming

Weigert toestandsveranderende verzoeken die cross-site afkomstig zijn. De controle draait als een before_request-hook en gebruikt de door de browser geleverde Sec-Fetch-Site-header (met de Origin-header als fallback voor oudere browsers, in combinatie met een microdot.cors.CORS-instantie).

class CSRF

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

De microdot.Microdot-instantie waarop geïnstalleerd moet worden. Optioneel; roep later initialize() aan indien niet opgegeven.

cors

De microdot.cors.CORS-instantie die de vertrouwde origins van de applicatie definieert. Vereist om terug te kunnen vallen op de Origin-header bij browsers die geen Sec-Fetch-Site versturen. Optioneel; zonder deze geldt alleen de Sec-Fetch-Site-controle.

protect_all

Als True (standaard) wordt elke route behalve GET, HEAD en OPTIONS automatisch beschermd. Routes kunnen individueel worden uitgezonderd met exempt(). Als False worden er standaard geen routes beschermd en kiezen individuele routes ervoor met protect().

allow_subdomains

Als True worden verzoeken van subdomeinen van de origins van de applicatie geaccepteerd (same-site Sec-Fetch-Site, of een overeenkomend origin-achtervoegsel).

initialize(app: Microdot, cors=None)

Koppel aan app als de constructie was uitgesteld.

exempt(f)

Decorator die een route uitzondert van CSRF-bescherming. Plaats deze direct na de route-decorator:

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

Decorator die CSRF-bescherming afdwingt op een route die anders zou zijn uitgezonderd (bijv. een GET-route of elke route wanneer protect_all=False).

SAFE_METHODS: list

Klasse-attribuut dat de methoden opsomt die standaard niet beschermd zijn – ['GET', 'HEAD', 'OPTIONS'].

Voorbeeld:

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}

Een verzoek wordt toegestaan wanneer Sec-Fetch-Site same-origin of none meldt (of same-site wanneer allow_subdomains=True). Als de header ontbreekt, wordt de Origin van het verzoek vergeleken met de CORS-toegestane lijst. Verzoeken zonder beide headers worden geaccepteerd (typisch voor directe API-aanroepen die niet onderhevig zijn aan browser-CSRF).