microdot.csrf — הגנת CSRF

דוחה בקשות משנות-מצב שמקורן בין-אתרי. הבדיקה רצה כהוק before_request ומשתמשת בכותרת Sec-Fetch-Site שהדפדפן מספק (עם כותרת Origin כגיבוי עבור דפדפנים ישנים יותר, כאשר היא מותאמת עם מופע microdot.cors.CORS).

class CSRF

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

מופע microdot.Microdot שעליו יש להתקין. אופציונלי; קראו ל-initialize() מאוחר יותר אם לא ניתן.

cors

מופע microdot.cors.CORS המגדיר את המקורות המהימנים של היישום. נדרש כדי לגבות באמצעות כותרת Origin בדפדפנים שאינם שולחים Sec-Fetch-Site. אופציונלי; ללא זה, חלה רק בדיקת ה-Sec-Fetch-Site.

protect_all

אם True (ברירת מחדל), כל נתיב למעט GET, HEAD ו-OPTIONS מוגן אוטומטית. ניתן לפטור נתיבים בנפרד באמצעות exempt(). אם False, אף נתיב אינו מוגן כברירת מחדל ונתיבים בודדים בוחרים להצטרף באמצעות protect().

allow_subdomains

אם True, בקשות מתת-דומיינים של מקורות היישום מתקבלות (same-site Sec-Fetch-Site, או סיומת מקור תואמת).

initialize(app: Microdot, cors=None)

מתחברת אל app אם החיבור נדחה.

exempt(f)

דקורטור שפוטר נתיב מהגנת CSRF. הציבו אותו ישירות אחרי דקורטור הנתיב:

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

דקורטור שכופה הגנת CSRF על נתיב שאחרת היה פטור (למשל נתיב GET או כל נתיב כאשר protect_all=False).

SAFE_METHODS: list

תכונת מחלקה המפרטת מתודות שאינן מוגנות כברירת מחדל – ['GET', 'HEAD', 'OPTIONS'].

דוגמה:

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}

בקשה מותרת כאשר Sec-Fetch-Site מדווח על same-origin או none (או same-site כאשר allow_subdomains=True). אם הכותרת נעדרת, ה-Origin של הבקשה מושווה לרשימת ההיתרים של CORS. בקשות ללא אף אחת מהכותרות מתקבלות (אופייני לקריאות API ישירות שאינן כפופות ל-CSRF של דפדפן).