Заголовки безопасности веб-приложений
Поделиться:
В этой статье разберемся с заголовками безопасности, которые можно часто встретить в результатах сканирования или аудита безопасности веб приложений на этапе разработки или уже опубликованного решения.
Часто, даже общедоступные системы анализа "качества" сайтов отмечают отсутствие тех или иных заголовков как уязвимость или ошибка конфигурации с рекомендацией устранения, но это не всегда имеет смысл. Попробую описать простым языком суть.
Content-Security-Policy
Основной цель. этого заголовка - защита от XSS. Т.е. от выполнения любых скриптов и файлов вне зоны что вы указали. Например:
Content-Security-Policy: script-src 'self'; img-src *
Директива 'self' означает что выполнение скриптов ограничено только самим сайтом. Но можно добавить любые домены, которые вы считаете для своего сайта доверенными. По умолчанию, если этого заголовка нет, сайт выполняет любые скрипты, и если каким то образом злоумышленник сможет внедрить код (например через комментарий) то ничего не помешает развивать атаку.
Strict-Transport-Security
Заголовок отвечающий за безопасность соединения. Его наличие гарантирует что соединение с сайтом будет зашифровано HTTPS.
Strict-Transport-Security: max-age=
Это полезный заголовок который обязателен для приложений что получают/отправляют чувствительную информацию. Но если сервис внутренний или работает только по http то такой заголовок будет только мешать.
X-Frame-Options
X-Frame-Options: SAMEORIGIN
Ограничивает использование frame или iframe другими сайтами. Это помогает против ситуаций когда злоумышленник использует ваш сайт в окне поверх своего. Если хотите этого избежать лучше его использовать, или использовать директиву "frame-ancestors" в CSP:
Content-Security-Policy: frame-ancestors 'self';
Это тоже самое.
X-Content-Type-Options
Заголовок защиты от атаки MIME sniffing, это когда сайт отдает файл с одним расширением, а браузер обрабатывает его по-другому, например как скрипт.
X-Content-Type-Options: nosniff
Этот заголовок защищает от такого и прямо запрещает чтение MIME-типов браузером. В современных условиях этот вектор атаки не такой опасный, но если вы приняли решение его использовать, следует предварительно протестировать в безопасной среде, т.к. неправильное выставление этого заголовка может нарушить работу веб-приложения.
X-XSS-Protection
Современные браузеры не поддерживают. Ставить не рекомендуется, кроме совсем специфичных сценариев (например старый веб-интерфейс камеры, который работает только на internet explorer).
Referrer-Policy
Заголовок приватности, при переходе на другой сайт (например по ссылке рекламы) регулирует то что увидит последний сайт. Это домен, страница и иногда параметры что оставлены в URL. Советую его оставлять таким:
Referrer-Policy: no-referrer
В таком случае последний сайт ничего не видит. Но если есть потребность для аналитики есть возможность оставить так:
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
Продвинутая настройка безопасности сайта. Через этот заголовок можно настраивать доступ к камере, микрофону, геолокации.
Permissions-Policy: camera=(), microphone=(), geolocation=(self), fullscreen=*
Очень полезный заголовок, расширяющий возможности защиты для конечных пользователей. Рекомендуется для крупных проектов с широкой пользовательской базой. Но не всеми браузерами поддерживается, на момент написания статьи в Firefox не работает.
CORS
Заголовки CORS - это отельная тема безопасности и конфиденциальности. Cross-Origin Resource Sharing - механизм безопасности, который регулирует как и какую информацию один ресурс может передавать другому. Без него возможна такая атака:
- Вы залогинены в своем банке
bank.com. В браузере сохранены ваши Cookie (файлы сессии). - Вы случайно заходите на злоумышленный сайт
attacker.com(например, через спам-ссылку). - На сайте
attacker.comвыполнятеся JavaScript-код, типа такого:
fetch('https://bank.com', {
method: 'POST',
body: JSON.stringify({ amount: 1000, to: 'hacker-id' })
});
- Если бы не было защиты: браузер отправил этот запрос вместе с вашими куками банка. Банк увидел родные куки и перевел деньги.
Конечно, так код не пишут, и этому препятствует множество других механизмов защиты, но принцип похож. От SCP этот подход отличается более тонкой настройкой и ещё некоторыми нюансами.
Access-Control-Allow-Origin: https://examlpe-app.com Access-Control-Allow-Methods: GET, OPTIONS Access-Control-Allow-Headers: Content-Type Access-Control-Max-Age: 86400
Таким образом пользователь, что регулярно пользуется вашим сайтом может быть уверен что его данные из личного кабинета никто не украдёт, если он случайно перешёл на "плохой" сайт.
Cross-Origin-Resource-Policy
Это заголовок безопасности, который работает аналогично CORS или CSP, с той лишь разницей, что он блокирует даже сам факт загрузки ресурса. Это помогает против атак, которые могут обойти стандартную CSP политику через уязвимости памяти.
Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Opener-Policy
Этот заголовок заставляет браузер разделить память между окнами и запустить их в разных изолированных процессах. Заголовок связан с механизмом Cross-Origin Isolation и что бы его обойти и нужен заголовок.
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy Заголовок что так же ограничивает загрузку контента для браузера пользователя но в связке с Cross-Origin-Resource-Policy.
Вариант заголовка когда запрещается загрузка всего, если это не указано в CORS или заголовке Cross-Origin-Resource-Policy.
Cross-Origin-Embedder-Policy: require-corp
Довольно полезный вариант заголовка который разрешает отправление всего, на браузер пользователя но без учетных данных и куки. Быстро и удобно.
Cross-Origin-Embedder-Policy: credentialless
Clear-Site-Data
Через этот заголовок регулируется механизм выхода из сессии - приказывает браузеру удалить куки, файлы, кэш что относятся к данному сайту.
Х-Permitted-Cross-Domain-Policies
Пример устаревшего заголовка что использовался для Flash. Некоторые сканеры могут показывать отсутствие подобных заголовков как проблему безопасности, чем по факту не является.
Вывод
Основная функция заголовков безопасности веб-приложений - это безопасность пользователей. Их установка не спасёт ваш сервер от SSRF или RCE. Злоумышленнику это никак не помешает, эти заголовки нужны только для того что бы защитить пользователей и (в редких случаях) межсервисное взаимодействие. Кроме того, следует понимать что заголовки безопасности это последний эшелон защиты, если вы установили и правильно настроили Content-Security-Policy это не значит что ваш сайт неуязвим к XSS. По факту, это просто рекомендуемая практика, мера предосторожности на случай если хакер сможет внедрить вредоносный код на страницу вашего сайта, но лучше этого вообще не допускать.
Регулярно обновлять CMS, зависимости, следовать практикам безопасности и экранировать пользовательские данные.
Как настраивать эти заголовки и надо-ли? Зависит от сайта:
- Одностраничный сайт-визитка, статический сайт, любой сайт без взаимодействия с пользователем - можно не настраивать или настраивать в последнюю очередь
- Небольшой сайт с личным кабинетом, сайт c аутентификацией во внутренней корпоративной сети, маленький интернет магазин - рекомендуется настроить хотя бы базовые заголовки (SCP, X-Frame-Options). Возможно, в вашем случае будет проще везде поставить SAMEORIGIN и реализовать загрузку всех ресурсов только с домена вашего сайта.
- Веб-приложение сервис с чувствительными пользовательскими данными - настройка заголовков обязательна, CORS, документирование межсервисных взаимодействий и гранулированные настройки безопасности.