10.12. CORS a CSRF

CORS a CSRF jsou dvě ochrany na straně prohlížeče, které kamera připojená k otevřenému internetu potřebuje vedle HTTPS a přihlášení. Každá zabere pár řádků na nastavení. Sekce níže definují pojem a ukazují integraci s microdotem.

10.12.1. Co dělá CORS

Cross-Origin Resource Sharing (CORS) je mechanismus prohlížeče, který umožňuje serveru přihlásit se k tomu, aby konkrétním jiným původům dovolil číst jeho odpovědi. Výchozí same-origin policy prohlížeče toto čtení blokuje: JavaScript na https://example.com nemůže číst odpovědi z https://yard-cam.example.com, protože jiný host se počítá jako jiný původ. CORS je způsob, jak na straně serveru udělit výjimky vybraným protějškům.

Pokud je dashboard servírován ze samotné kamery, je každý požadavek same-origin a CORS nic nedělá. Nastavení má význam, když dashboard žije jinde – veřejná URL jako https://app.example.com, která komunikuje s kamerou na https://yard-cam.example.com:

from microdot.cors import CORS

cors = CORS(
    app,
    allowed_origins=['https://app.example.com'],
    allow_credentials=True,
    max_age=86400,
)

allowed_origins je seznam původů, kterým je povoleno číst odpovědi kamery. Původ dashboardu a jen původ dashboardu – nikoli * – aby web třetí strany nemohl odpovědi kamery číst omylem.

allow_credentials=True umožňuje, aby cross-origin požadavky obsahovaly session cookie, což dashboard potřebuje, aby zůstal přihlášený přes hranici původu.

max_age=86400 říká prohlížeči, že může výsledek preflightu kešovat na jeden den. Prohlížeče před každým cross-origin voláním, které používá jiné metody než GET/HEAD/POST nebo odesílá vlastní hlavičky, vyšlou navíc požadavek OPTIONS; max_age snižuje tuto režii na jeden preflight za den na routu.

10.12.2. Co dělá CSRF

Cross-Site Request Forgery (CSRF) je útok, při kterém škodlivá stránka přiměje prohlížeč uživatele vyslat ověřený požadavek na důvěryhodný server. I s nasazeným CORS skrytý <form> na evil.com, který provede POST na https://yard-cam.example.com/config, dorazí ke kameře a prohlížeč připojí session cookie kamery – cookies sledují cílového hosta, nikoli původ stránky, která požadavek odesílá – takže kamera POST radostně zpracuje, jako by jej provedl majitel.

Ochrana CSRF tyto požadavky odmítá. microdot.csrf.CSRF přidává middleware, který u každého požadavku měnícího stav zkoumá hlavičku Sec-Fetch-Site a odmítne vše, co není označeno jako same-origin (nebo co pochází z původu povoleného CORS):

from microdot.csrf import CSRF

CSRF(app, cors=cors)

Předání instance cors umožňuje middlewaru zahrnout povolený původ dashboardu – kamera stále přijímá POSTy z dashboardu, i když jsou cross-origin.

Sec-Fetch-Site nastavují moderní prohlížeče automaticky; kamera nemusí na straně klienta dělat nic. U starších prohlížečů, které hlavičku neodesílají, je záložní kontrolou seznam povolených původů CORS.

10.12.3. Výjimky pro webhooky

Pokud kamera potřebuje koncový bod webhooku, který přijímá POSTy z cloudové služby třetí strany – například callback od poskytovatele archivu – označte routu pomocí @csrf.exempt, aby ji middleware propustil. Handler zodpovídá za ověření požadavku jiným způsobem – obvykle Hash-based Message Authentication Code (HMAC) nad payloadem, vypočítaný pomocí tajemství sdíleného kamerou a třetí stranou, což dokazuje, že požadavek pochází od někoho, kdo tajemství znal. Kamera na dvorku žádné z toho nemá, ale dekorátor je tu, až jej budete potřebovat.

10.12.4. Čtyřřádkový základ

Jakmile je HTTPS na místě, doporučený stack pro jakékoli nasazení kamery do internetu je:

Session(app, secret_key=SECRET,
        cookie_options={'http_only': True, 'secure': True})
login = Login()
cors = CORS(app, allowed_origins=[...], allow_credentials=True)
CSRF(app, cors=cors)

Session a přihlášení dříve v kapitole, CORS a CSRF zde, HTTPS z předchozího tématu. Tyto čtyři části se vrství na sebe a nepřekáží žádné routě.

Kamera je nyní bezpečná pro připojení k otevřenému internetu – HTTPS, přihlášení, CSRF, CORS.