10.12. CORS та CSRF

CORS і CSRF – це два захисних механізми на стороні браузера, які потрібні камері, підключеній до відкритого інтернету, разом із HTTPS та входом. Кожен налаштовується кількома рядками. Нижченаведені розділи визначають поняття і демонструють інтеграцію з microdot.

10.12.1. Що робить CORS

Cross-Origin Resource Sharing (CORS) – це механізм браузера, що дозволяє серверу дозволяти конкретним іншим джерелам читати його відповіді. Стандартна політика одного джерела браузера блокує таке читання: JavaScript на https://example.com не може читати відповіді від https://yard-cam.example.com, оскільки різний хост вважається різним джерелом. CORS – це серверний спосіб надавати виключення для вибраних партнерів.

Якщо панель моніторингу обслуговується з самої камери, кожен запит є з одного джерела і CORS нічого не робить. Налаштування має значення, коли панель моніторингу розташована десь в іншому місці – публічний URL, наприклад https://app.example.com, що спілкується з камерою на 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 – це список джерел, яким дозволено читати відповіді камери. Лише джерело панелі моніторингу і лише джерело панелі моніторингу – не * – тому сторонній сайт не може випадково читати відповіді камери.

allow_credentials=True дозволяє запитам між різними джерелами включати сесійний cookie, що необхідно панелі моніторингу для підтримки входу між джерелами.

max_age=86400 повідомляє браузеру, що він може кешувати результат попереднього запиту на один день. Браузери надсилають додатковий запит OPTIONS перед будь-яким міжджерельним викликом, що використовує методи, відмінні від GET/HEAD/POST, або надсилає нестандартні заголовки; max_age зменшує цей overhead до одного попереднього запиту на день на маршрут.

10.12.2. Що робить CSRF

Cross-Site Request Forgery (CSRF) – це атака, за якої зловмисна сторінка змушує браузер користувача відправити автентифікований запит на довірений сервер. Навіть при включеному CORS, прихована <form> на evil.com, що робить POST до https://yard-cam.example.com/config, досягне камери, і браузер прикріпить сесійний cookie камери – cookies слідують за хостом призначення, а не за джерелом сторінки, що робить запит – тому камера з радістю обробляє POST, ніби це власник.

Захист CSRF відхиляє такі запити. microdot.csrf.CSRF додає проміжне програмне забезпечення, що перевіряє заголовок Sec-Fetch-Site на кожному запиті, що змінює стан, і відхиляє все, що не позначено як same-origin (або не надходить із дозволеного джерела CORS):

from microdot.csrf import CSRF

CSRF(app, cors=cors)

Передача екземпляра cors дозволяє проміжному забезпеченню враховувати дозволене джерело панелі моніторингу – камера все одно приймає POST від панелі, навіть якщо вони міжджерельні.

Sec-Fetch-Site встановлюється сучасними браузерами автоматично; камері не потрібно нічого робити на стороні клієнта. Для старіших браузерів, що не надсилають цей заголовок, список дозволених джерел CORS є резервною перевіркою.

10.12.3. Виключення вебхуків

Якщо камері потрібен ендпоінт вебхука для прийому POST від стороннього хмарного сервісу – наприклад, зворотний виклик від постачальника архіву – позначте маршрут @csrf.exempt, щоб проміжне забезпечення пропустило його. Обробник відповідає за перевірку запиту іншим способом – зазвичай Hash-based Message Authentication Code (HMAC) над корисним навантаженням, обчислений за допомогою секрету, що знають камера і третя сторона, що доводить, що запит надійшов від когось, хто знав секрет. У камері заднього двору нічого такого немає, але декоратор є, коли він вам потрібен.

10.12.4. Базовий чотирирядковий стек

Після того, як HTTPS налаштовано, рекомендований стек для будь-якого розгортання камери, що виходить в інтернет:

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)

Сесія та вхід раніше в цьому розділі, CORS і CSRF тут, HTTPS з попередньої теми. Чотири компоненти накладаються один на одного і не заважають кожному маршруту.

Камера тепер безпечна для виходу у відкритий інтернет – HTTPS, вхід, CSRF, CORS.