10.12. CORS i CSRF#
CORS i CSRF to dwa zabezpieczenia po stronie przeglądarki, których kamera wystawiona na otwarty internet potrzebuje obok HTTPS i logowania. Każde wymaga kilku linii konfiguracji. Poniższe sekcje definiują pojęcie i pokazują integrację z microdotem.
10.12.1. Do czego służy CORS#
Cross-Origin Resource Sharing (CORS) to mechanizm przeglądarki pozwalający serwerowi świadomie zezwolić wybranym innym źródłom na odczyt jego odpowiedzi. Domyślna polityka tego samego źródła przeglądarki blokuje ten odczyt: JavaScript na https://example.com nie może odczytać odpowiedzi z https://yard-cam.example.com, ponieważ inny host liczy się jako inne źródło. CORS to sposób, w jaki serwer udziela wyjątków wybranym partnerom.
Jeśli panel jest serwowany z samej kamery, każde żądanie pochodzi z tego samego źródła i CORS nic nie robi. Konfiguracja ma znaczenie, gdy panel mieszka gdzie indziej – publiczny adres URL taki jak https://app.example.com, który komunikuje się z kamerą pod 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 to lista źródeł, którym wolno odczytywać odpowiedzi kamery. Źródło panelu i tylko źródło panelu – nie * – aby witryna strony trzeciej nie mogła przypadkiem odczytać odpowiedzi kamery.
allow_credentials=True pozwala żądaniom z innego źródła dołączać ciasteczko sesji, czego panel potrzebuje, aby pozostać zalogowanym ponad granicą źródeł.
max_age=86400 mówi przeglądarce, że może buforować wynik kontroli wstępnej przez dobę. Przeglądarki wysyłają dodatkowe żądanie OPTIONS przed każdym wywołaniem z innego źródła, które używa metod innych niż GET/HEAD/POST lub wysyła niestandardowe nagłówki; max_age ogranicza ten narzut do jednej kontroli wstępnej dziennie na trasę.
10.12.2. Do czego służy CSRF#
Cross-Site Request Forgery (CSRF) to atak, w którym złośliwa strona sprawia, że przeglądarka użytkownika wysyła uwierzytelnione żądanie do zaufanego serwera. Nawet gdy CORS jest na miejscu, ukryty <form> na evil.com, który wykonuje POST do https://yard-cam.example.com/config, dotrze do kamery, a przeglądarka dołączy ciasteczko sesji kamery – ciasteczka podążają za hostem docelowym, a nie za źródłem strony wysyłającej żądanie – więc kamera ochoczo przetworzy POST tak, jakby pochodził od właściciela.
Ochrona CSRF odrzuca takie żądania. microdot.csrf.CSRF dodaje oprogramowanie pośredniczące, które sprawdza nagłówek Sec-Fetch-Site w każdym żądaniu zmieniającym stan i odrzuca wszystko, co nie jest oznaczone jako same-origin (lub nie pochodzi ze źródła dozwolonego przez CORS):
from microdot.csrf import CSRF
CSRF(app, cors=cors)
Przekazanie instancji cors pozwala oprogramowaniu pośredniczącemu uznać dozwolone źródło panelu za już zatwierdzone – kamera nadal akceptuje żądania POST z panelu, mimo że pochodzą z innego źródła.
Sec-Fetch-Site jest ustawiany automatycznie przez nowoczesne przeglądarki; kamera nie musi robić nic po stronie klienta. Dla starszych przeglądarek, które nie wysyłają tego nagłówka, lista dozwolonych źródeł CORS jest kontrolą awaryjną.
10.12.3. Wyłączanie webhooków#
Jeśli kamera potrzebuje punktu końcowego webhooka, aby przyjmować żądania POST od usługi chmurowej strony trzeciej – na przykład wywołanie zwrotne od dostawcy archiwum – oznacz trasę jako @csrf.exempt, aby oprogramowanie pośredniczące ją przepuściło. Handler jest odpowiedzialny za weryfikację żądania w inny sposób – zwykle za pomocą Hash-based Message Authentication Code (HMAC) nad ładunkiem, obliczanego z sekretem współdzielonym przez kamerę i stronę trzecią, co dowodzi, że żądanie pochodzi od kogoś, kto znał sekret. Kamera na podwórku nie ma żadnego z nich, ale dekorator jest na miejscu, gdy go potrzebujesz.
10.12.4. Czterowierszowa podstawa#
Gdy HTTPS jest na miejscu, zalecany stos dla każdego wdrożenia kamery wystawionej na internet to:
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)
Sesja i logowanie wcześniej w rozdziale, CORS i CSRF tutaj, HTTPS z poprzedniego tematu. Te cztery elementy układają się jeden na drugim i nie wchodzą w drogę żadnej trasie.
Kamera może teraz bezpiecznie zmierzyć się z otwartym internetem – HTTPS, logowanie, CSRF, CORS.