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 сокращает эти накладные расходы до одного предзапроса в сутки на каждый маршрут.
10.12.2. Что делает CSRF¶
Cross-Site Request Forgery (CSRF) – это атака, при которой вредоносная страница заставляет браузер пользователя отправить аутентифицированный запрос доверенному серверу. Даже при включённом CORS скрытая <form> на evil.com, отправляющая POST на https://yard-cam.example.com/config, дойдёт до камеры, и браузер прикрепит cookie сессии камеры – cookie следуют за хостом назначения, а не за источником страницы, делающей запрос – так что камера спокойно обработает 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.