Браузерная безопасность (часть 2)
Ранее в первой части я разобрал SOP, CORS и Content-Type. Теперь продолжу тему: почему браузер сам отправляет авторизацию, как SameSite влияет на CSRF, от чего защищает HttpOnly и почему CORS не спасает от clickjacking и что тогда спасает.
━━━━━━━━━━ Откуда появляется потделка запроса на стороне клиента / CSRF ━━━━━━━━━━
Главная идея простая: ➤ если браузер сам добавляет авторизацию, атакующий может попытаться заставить браузер жертвы выполнить действие на целевом сайте.
Пользователь входит в сервис, браузер сохраняет session cookie и при подходящем запросе сам добавляет: • Cookie: session=...
━━━━━━━━━━ Что такое SameSite ━━━━━━━━━━
SameSite — атрибут cookie, который определяет, когда её можно отправлять в зависимости от контекста запроса.
Не стоит путать origin и site: Origin = scheme + host + port Site = scheme + registrable domain
• https://app.example.com и https://api.example.com — разные origin, но один site • http://example.com и https://example.com — разные site
➤ SameSite=Strict Cookie отправляется только в same-site контексте. Это самый жёсткий режим, но он ломает переходы с внешних сайтов.
➤ SameSite=Lax Cookie обычно не отправляется в cross-site iframe и fetch, но может уйти при top-level переходе с безопасным методом, например GET. Lax снижает риск CSRF, но не заменяет CSRF-токены.
➤ SameSite=None; Secure Cookie можно отправлять в cross-site контексте, но только по HTTPS. Такой режим нужен для некоторых SSO и интеграций, но требует отдельной защиты от CSRF.
⚠️ Важно учитывать: если разработчики не указали атрибут SameSite, современные Chromium-браузеры по умолчанию обрабатывают cookie как SameSite=Lax.
Однако для таких cookie существует исключение, известное как Lax+POST. В течение примерно двух минут после создания cookie браузер может отправить её вместе с межсайтовым POST-запросом, если запрос приводит к навигации всей вкладки. После истечения этого времени начинают действовать обычные ограничения Lax, и cookie больше не будет добавляться к подобным cross-site POST-запросам.
━━━━━━━━━━ От чего защищает HttpOnly ━━━━━━━━━━
HttpOnly запрещает JavaScript читать cookie через document.cookie. Это усложняет прямую кражу session cookie при XSS, но: • не мешает браузеру отправлять cookie • не защищает от CSRF • не устраняет саму XSS
━━━━━━━━━━ Почему CORS не спасает от clickjacking ━━━━━━━━━━
Представим: evil.com └── <iframe src="https://bank.com">
CORS отвечает на вопрос: ➤ может ли JavaScript одного origin прочитать ответ другого origin?
Но iframe — это не fetch и не XHR. Браузер просто открывает страницу как вложенный документ.
SOP не даст evil.com читать DOM страницы bank.com, но сама страница может отобразиться в iframe, если сервер это не запретил.
Поэтому даже идеально настроенный CORS не защищает от clickjacking. Основная защита: • Content-Security-Policy: frame-ancestors • X-Frame-Options для совместимости
Подробнее про CSP: ➥ https://setka.ru/posts/019cb6cb-fdfe-7c71-99b6-c27bf36aa093
━━━━━━━━━━ Как SameSite влияет на clickjacking ━━━━━━━━━━
Если bank.com открыт внутри cross-site iframe на evil.com: • Strict — cookie не уйдёт • Lax — обычно тоже не уйдёт: iframe не является top-level navigation • None; Secure — cookie может быть отправлена
Из-за этого Strict и Lax могут мешать clickjacking по авторизованной зоне: страница откроется, но пользователь внутри iframe окажется без сессии.
Но считать SameSite полноценной защитой нельзя: ➤ frame-ancestors запрещает нежелательное встраивание ➤ SameSite только ограничивает отправку cookie
━━━━━━━━━━ Мини-итог ━━━━━━━━━━
• SameSite ограничивает отправку cookie между site • HttpOnly запрещает JS читать cookie, но не мешает браузеру её отправлять • CORS не запрещает отображение страницы в iframe • clickjacking блокируется через frame-ancestors и X-Frame-Options
Каждый механизм решает свою задачу и работает как отдельный слой защиты.
#AppSec #CyberSecurity #IT #WebSecurity #Cookies #SameSite #HttpOnly #CSRF #Clickjacking #CORS #SOP