microdot.csrf --- การป้องกัน CSRF

ปฏิเสธคำขอที่เปลี่ยนแปลงสถานะซึ่งมาจากต้นทางข้ามไซต์ การตรวจสอบทำงานเป็น hook 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 หรือ suffix ต้นทางที่ตรงกัน)

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

แอตทริบิวต์คลาสที่แสดงรายการ method ที่ไม่ได้รับการป้องกันโดยค่าเริ่มต้น -- ['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 ของเบราว์เซอร์)