- Полное руководство по настройке HTTP-заголовков для безопасности
- Важные заголовки для безопасности
- Content-Security-Policy
- Strict-Transport-Security
- X-Content-Type-Options
- Cache-Control
- Expires
- X-Frame-Options
- Access-Control-Allow-Origin
- Set-Cookie
- X-XSS-Protection
- Пример настроек веб-сервера
- Конфигурация Apache
- Конфигурация Nginx
- Настройка заголовка уровня приложения
- Java и Spring
- Python / Django
- Выводы
- Проверяем и оптимизируем HTTP-заголовки сайта
- Что такое HTTP-заголовки?
- Список HTTP-заголовков
- HTTP Security Headers
Полное руководство по настройке HTTP-заголовков для безопасности
Компании, продающие «системы показателей безопасности», сейчас на подъеме, их влияние в сфере корпоративных продаж растет. К тому же есть те, кого низкий рейтинг безопасности у продавцов смущает, и те, кто хотя бы однажды, глядя на рейтинг, отказался от покупки, — я с такими людьми общался.
Я посмотрел, как эти компании вычисляют показатели безопасности других компаний. Оказалось, они смотрят на сочетание использования НТТР-заголовка для безопасности и репутации IP-адресов.
Репутация IP-адреса основывается на данных черных списков и списков спамеров в сочетании с данными о владельце общедоступного IP-адреса. Она, в принципе, должна быть чистой, если ваша компания не рассылает спам и в состоянии быстро определить и остановить вредоносное внедрение. Использование заголовка безопасности НТТР вычисляется аналогично тому, как работает Observatory от Mozilla.
Таким образом, рейтинг большинства компаний, в основном, определяется заголовками, включенными на общедоступных веб-сайтах для безопасности.
Настроить заголовок правильно — это недолго (серьезной проверки не потребуется), но это улучшит безопасность сайта и поможет не растерять покупателей, для которых безопасность — не пустой звук
В ценности упомянутой методики проверки я сомневаюсь, к том же ценник за услугу выставлен заоблачный. Вряд ли компании-поставщики этой услуги способны определить безопасность ресурса с заявленной точностью. Впрочем, ситуация лишний раз подчеркивает, как важно сесть и уделить время тому, чтобы включить и настроить правильные заголовки.
В этой статье я буду говорить о наиболее часто проверяемых заголовках, для каждого посоветую значения безопасности и приведу пример настройки. В конце дам примеры настройки для распространенных приложений и веб-серверов.
Важные заголовки для безопасности
Content-Security-Policy
CSP применяется, чтобы предотвращать межсайтовый скриптинг — путем определения, какие ресурсы могут быть загружены. Из всего списка этот заголовок отнимет больше остальных времени на создание и правильную поддержку, а еще больше других подвержен рискам. Разрабатывая CSP, тщательно его проверяйте — если вдруг заблокируете используемый вами же источник, то нарушите функциональность собственного сайта.
Для предварительной версии можно использовать замечательный инструмент — расширение для браузера Mozilla, Laboratory CSP. Установите его в браузере, тщательно изучите сайт, для которого хотите создать CSP, а после используйте сгенерированную CSP на своем сайте. В идеале, нужно еще переработать JavaScript, так что можно удалить директиву «unsafe inline».
CSP может показаться сложной и сбить с толку, поэтому, если хотите углубиться в тему, посетите официальный сайт.
Предварительно можно настроить CSP так (на боевом сайте она, скорее всего, потребует множества модификаций). Добавьте в каждый раздел вашего сайта домены.
Strict-Transport-Security
Этот заголовок сообщает браузеру, что на сайт заходить можно только по протоколу HTTPS — всегда включайте его, если на вашем сайта активирован HTTPS. Включите его на всех используемых субдоменах, если таковые имеются.
X-Content-Type-Options
Благодаря этому заголовку браузеры придерживаются типов MIME, установленных приложением, что помогает предотвратить часть атак с межсайтовым скриптингом.
Также он снижает риск неожиданного поведения приложения, когда браузер неверно «угадывает» тип контента на сайте — например, если разработчик обозначает страницу «HTML», а браузер видит JavaScript и пытается отрисовать страницу соответственно. Также благодаря этому заголовку браузер всегда держится установленных сервером MIME-типов.
Cache-Control
Этот будет позаковыристее прочих, потому что для разных типов контента вам наверняка нужны разные политики кэширования.
Никакая деликатная информация — вроде страницы пользователя или страницы оплаты товара — не должна кэшироваться. Одна из причин для этого — чтобы другой пользователь компьютера не нажал кнопку «назад», не прочел историю и не увидел личных данных другого пользователя.
Впрочем, кэшировать можно и нужно те страницы, которые обновляются редко, например статические ресурсы (картинки, файлы CSS и JS). Кэширование можно настроить на постраничной основе, или используя regex в настройках сервера.
Expires
Этот заголовок устанавливает время, на которое текущий запрос сохраняется в кэше. Он игнорируется, если включен заголовок Cache-Control max-age, так что мы включаем его только на случай, если его проверяет простенький сканер — без учета контроля кэширования.
Мы предполагаем, что в целях безопасности браузер не кэширует ничего, так что дата в заголовке всегда будет в прошлом.
X-Frame-Options
Этот заголовок разрешает отображение сайта в iFrame.
Поместив ваш веб-сайт в iFrame, вредоносный ресурс получает возможность произвести кликджекинг атаку — запустив некий JavaScript, который обманом вынудит пользователя кликнуть по iFrame, а после начнет взаимодействовать с ресурсом от его, пользователя, имени (то есть человек кликнет по вредоносной ссылке или кнопке, даже не подозревая об этом!).
Этот заголовок всегда надо настраивать на отказ, исключение — если вы намеренно используете фреймы. Тогда заголовок нужно настраивать на тот же источник. Если вы по умолчанию используете фреймы с другим сайтом, занесите сторонний домен в белый список.
Следует также отметить, что этот заголовок замещается директивой CSP frame-ancestors. Я его рекомендую пока включать, но только для того, чтобы заткнуть инструменты для проверки заголовков, в будущем от него скорее всего избавятся.
Access-Control-Allow-Origin
Этот заголовок сообщает браузеру, внешний код каких посторонних сайтов имеет право делать запросы к определенной странице. Настройки по умолчанию обычно правильные, но если надо — можно и поменять.
Например, сайт А содержит некий JavaScript, который хочет сделать запрос к сайту В. Сайт В должен ответить на этот запрос — если заголовок разрешает сайту А сделать запрос. Если нужно настроить множество источников, подробности на странице на MDN.
Тут можно слегка запутаться, поэтому я составил схему — проиллюстрировать, как работает этот заголовок:
Поток данных с Access-Control-Allow-Origin
Set-Cookie
Убедитесь, что ваши cookies устанавливаются только через протокол HTTPS (с шифрованием), и что к ним нет доступа через JavaScript. Эти файлы можно посылать, только если ваш сайт тоже поддерживает HTTPS, как и должно быть. Всегда нужно выставлять вот такие флаги:
Пример определения Cookie:
Подробнее — в отличной документации по cookies от Mozilla.
X-XSS-Protection
Этот заголовок приказывает браузеру прервать выполнение обнаруженных атак межсайтового скриптинга. Включая его, вы не сильно рискуете, но перед запуском в производственную среду все равно протестируйте.
Пример настроек веб-сервера
Вообще, в настройках сервера лучше всего добавлять заголовки на весь сайт. Исключение — файлы cookie, поскольку они определяются в самом приложении.
Советую, прежде чем добавить на сайт заголовки, сперва свериться с Observatory или вручную заглянуть в заголовки — проверить, какие уже установлены. Некоторые движки сайтов и сервера самостоятельно все установят, поэтому просто реализуйте нужные вам заголовки или измените те, которые в этом нуждаются.
Конфигурация Apache
Пример настройки Apache в .htaccess:
Конфигурация Nginx
Настройка заголовка уровня приложения
Если у вас нет доступа к веб-серверу или требования к настройке заголовков сложные, то вам наверняка придется настроить их в самом приложении. Обычно для всего сайта это осуществляется с помощью промежуточного ПО, или на основе однократной установки заголовков при каждом запросе.
Для краткости в каждый пример я включил только по одному заголовку. Вы же добавляйте по тому же способу все, которые нужны.
Добавьте global mount path:
Java и Spring
У меня мало опыта работы со Spring, но у Baeldung есть отличное руководство по настройке заголовков в Spring.
Я не знаком с разнообразными средами PHP. Ищите промежуточное ПО для запросов. Для единичного запроса все просто.
Python / Django
Django включает настраиваемое промежуточное ПО для обеспечения безопасности, которое выполнит за вас все эти настройки. Активируйте сначала их.
Ответы некоторых страниц можно трактовать как словарь. В Django есть особый способ работы с кэшированием, и если хотите настроить заголовки кэширования таким образом, с ним надо ознакомиться.
Выводы
Настройка заголовков — процесс относительно простой и быстрый, зато дает прирост уровня безопасности сайта — в плане защиты данных, от межсайтового скриптинга и кликджекинга.
В будущем вы оградите себя от срыва сделок, потому что ваш рейтинг безопасности останется на уровне. Практика его оценки на основе рассмотренных мной параметров набирает обороты, и мне кажется, ее роль в ближайшие годы в сфере продаж только усилится.
Дайте знать, если я упустил какой-то важный заголовок!
Источник
Проверяем и оптимизируем HTTP-заголовки сайта
О чем будет сегодняшний блог? О HTTP-заголовках. Многие, к сожалению, забывают или просто игнорируют их. А по факту: некоторые HTTP-заголовки не только бессмысленны, но и существенно ухудшают кибербезопасность сайта, предоставляя конфиденциальную информацию любому желающему. Например, просмотрев HTTP-headers сайта конкурента, я смог узнать текущую версию веб-сервера, версию PHP, версию программного обеспечения на сервере, и даже название шаблона сайта. Но есть и полезные HTTP-заголовки, которые наоборот улучшают безопасность сайта. Обо всем этом я расскажу в моей статье.
Что такое HTTP-заголовки?
HTTP-заголовки — это специальные параметры, содержащие информацию о браузере клиента, запрошенной странице, сервере, и передаются по протоколу HTTP (Hypertext Transfer Protocol — Протокол Передачи Гипертекста).
Получить HTTP Headers сайта можно разными способами:
- С помощью онлайн-сервиса BERTAL.RU
- С помощью расширения для браузера Firebug или Chrome/Firefox Dev Tools
- В консоли Linux командой: curl -I https://example.com
Список HTTP-заголовков
| Заголовок | Значение | Статус |
|---|---|---|
| date | Текущие дата и время | Требуется по протоколу |
| content-type | Язык разметки, тип контента | Обычно требуется браузером |
| server | Сигнатура веб-сервера | Необязателен |
| content-length | Размер контента в байтах | Полезен |
| last-modified | Последнее изменение страницы | Полезен |
| cache-control | Управляет кешированием сайта. Указывает правила кеширования . Эффективность проверить можно тут . | Полезен |
| content-encoding | Кодировка страницы | Требуется для сжатого контента |
| expires | Дата предполагаемого срока истечения актуальности контента. Если в ответе с сервера установлен заголовок Cache-Control с директивами «max-age» или «s-maxage», заголовок Expires игнорируется. | Необязателен |
| x-powered-by | Версия PHP сайта | Необязателен |
| pragma | Является заголовком HTTP/1.0 и отвечает за кеширование. Тем не менее, не может служить надежной заменой заголовку «Cache-Control: no-cache», хотя и ведет себя аналогичным образом когда поле заголовка Cache-Control опущено в запросе. На некоторых CMS включен по умолчанию и взаимодействует с Cache Control. В принципе, выполняет какую-то работу. | Необязателен для HTTP/2 |
| x-frame-options | Защита от кликджекинга | Полезен |
| access-control-allow-origin | Проверка, может ли ресурс быть доступен для контента на текущем домене. | Полезен |
| x-content-type-options | Блокировка перехвата содержимого MIME | Полезен |
| link | Указывает на логически связный с сущностью ресурс | Полезен |
| age | Количество секунд с момента последней модификации ресурса | Полезен |
| x-cache | Непонятный заголовок, который добавляют CDN-сервисы | Необязателен |
| x-xss-protection | Защита от XSS-атак | Полезен |
| strict-transport-security | HSTS заголовок, который уведомляет ботам, что доступ к сайту должен быть только по https. Форсирует безопасность сайта. | Полезен |
| via | Общее поле HTTP заголовкаVia служит для отображения списка версий протокола HTTP, названий и версий прокси-серверов, через которые прошло сообщение. | Необязателен |
| p3p | Нужен для IE8 чтобы принимать cookies третьих лиц. Устаревший. | Необязателен |
| expect-ct | Нужный для декларирования клиенту, что используется механизм Certificate Transparency – то есть сервер получил сертификат через публично журналируемый CA, и запись о выдаче данного сертификата есть и доступна. | Полезен |
| content-language | Язык контента | Спорно |
| x-aspnet-version | Версия сервера ASP.NET | Необязателен |
| access-control-allow-credentials | Проверка безопасности. Нужен для работы некоторых jquery-плагинов. | Полезен |
| x-robots-tag | Заголовок X-Robots-Tag используется как элемент HTTP-ответа для определенного URL. В заголовках X-Robots-Tag поддерживаются те же директивы, что и в мета тегах robots. | Не имеет значения для браузеров, используется поисковыми ботами Google |
| x-ua-compatible | Призывает Internet Explorer работать в определённом режиме документа. Остальные браузеры должны игнорировать данную прагма директиву. | Необязателен |
| access-control-allow-methods | Контроль безопасности | Полезен |
| access-control-allow-headers | Контроль безопасности | Полезен |
Жирным обозначены заголовки, которые можно без риска удалить из ответа сервера.
HTTP Security Headers
Заголовки безопасности предотвращают атаки на сайт, межсайтовый скриптинг, инъекции и эксплойты.
Ниже, подаю заготовку директив для .htaccess, которая добавляет все необходимые заголовки безопасности на сайт:
[php]# BEGIN SECURITY_HEADERS
Header always set Strict-Transport-Security: «max-age=63072000; includeSubDomains; preload» env=HTTPS
Header always set Content-Security-Policy «upgrade-insecure-requests»
Header always set X-XSS-Protection «1; mode=block»
Header always set X-Content-Type-Options «nosniff»
Header always set Referrer-Policy: «no-referrer-when-downgrade»
Header always set Expect-CT «max-age=7776000, enforce»
Header always set X-Frame-Options «sameorigin»
Header always set Permissions-Policy: «accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()»
# END SECURITY_HEADERS[/php]
Источник