🌐 Заголовки безопасности HTTP – полное руководство

Статьи

Репутация IP основана на черных списках и списках спама в сочетании с публичными данными о владении.

Эти данные, как правило, должны быть чистыми, если ваша компания не занимается спамом и может быстро обнаружить и остановить заражение вредоносным ПО.

Поэтому для большинства компаний их рейтинг в значительной степени определяется тем, какие заголовки безопасности установлены на веб-сайтах, предназначенных для общего пользования.

Установка правильных заголовков может быть выполнена быстро (обычно без значительного тестирования), может повысить безопасность веб-сайта и теперь может помочь вам заключать сделки с клиентами, заботящимися о безопасности.

Важные заголовки безопасности

Content-Security-Policy

CSP используется для предотвращения межсайтового скриптинга, определяя, какие ресурсы разрешено загружать.

Из всех пунктов этого списка этот, пожалуй, самый трудоемкий для создания и правильной поддержки и самый подверженный рискам.

При разработке CSP тщательно протестируйте его – блокировка источника контента, который ваш сайт использует допустимым образом, приведет к нарушению функциональности сайта.

Отличным инструментом для создания первого наброска является расширение браузера Mozilla Laboratory CSP.

Установите его в свой браузер, тщательно просмотрите сайт, для которого вы хотите создать CSP, а затем используйте созданный CSP на своем сайте.

В идеале, также поработайте над рефакторингом JavaScript, чтобы не оставалось встроенных скриптов, и тогда вы сможете удалить директиву ‘unsafe inline’.

CSP могут быть сложными и запутанными, поэтому, если вы хотите более глубокого погружения, обратитесь к официальному сайту.

Хорошей начальной CSP может быть следующая (скорее всего, она потребует много изменений на реальном сайте).

Добавьте домены в каждый раздел, который содержит ваш сайт.

# Default to only allow content from the current site
# Allow images from current site and imgur.com
# Don't allow objects such as Flash and Java
# Only allow scripts from the current site
# Only allow styles from the current site
# Only allow frames from the current site
# Restrict URL's in the <base> tag to current site
# Allow forms to submit only to the current site
Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';

Strict-Transport-Security

Этот заголовок сообщает браузеру, что доступ к сайту должен осуществляться только через HTTPS – всегда включайте его, если на вашем сайте включен HTTPS.

Если вы используете поддомены, я также рекомендую использовать этот заголовок для всех используемых поддоменов.

Strict-Transport-Security: max-age=3600; includeSubDomains

X-Content-Type-Options

Этот заголовок гарантирует, что типы MIME, установленные приложением, будут соблюдаться браузерами.

Это может помочь предотвратить некоторые типы обхода межсайтового скриптинга.

Он также уменьшает неожиданное поведение приложения, когда браузер может неправильно “угадать” содержимое, например, когда разработчик обозначает страницу как “HTML”, но браузер считает, что она выглядит как JavaScript, и пытается отобразить ее как JavaScript.

Этот заголовок гарантирует, что браузер всегда будет принимать тип MIME, установленный сервером.

X-Content-Type-Options: nosniff

Cache-Control3

Этот параметр немного сложнее других, поскольку вы, скорее всего, хотите использовать разные политики кэширования для разных типов контента.

Любая страница с конфиденциальными данными, например, страница пользователя или страница оформления заказа, должна быть установлена на no-cache.

Одна из причин этого – предотвращение того, чтобы кто-то на общем компьютере мог нажать кнопку “назад” или просмотреть историю и получить возможность просмотреть личную информацию.

Однако страницы, которые меняются редко, такие как статические активы (изображения, CSS-файлы и JS-файлы), полезно кэшировать.

Это может быть сделано на основе каждой страницы или с помощью regex в конфигурации сервера.

# Не кэшировать по умолчанию
Header set Cache-Control no-cache

# Кэширование статических активов на 1 день
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
    Header set Cache-Control "max-age=86400, public"
</filesMatch>

Expires

Устанавливает время, в течение которого кэш должен завершить текущий запрос.

Он игнорируется, если установлен заголовок Cache-Control max-age, поэтому мы задаем его только на случай, если сканер будет проверять его без учета cache-control.

В целях безопасности мы будем считать, что браузер не должен ничего кэшировать, поэтому мы установим дату, которая всегда оценивается как прошедшая.

Expires: 0

X-Frame-Options

Этот заголовок указывает, следует ли разрешить отображение сайта в iFrame.

Если вредоносный сайт помещает ваш сайт в iFrame, он может выполнить атаку click jacking, запустив JavaScript, который будет перехватывать нажатия мыши на iFrame и затем взаимодействовать с сайтом от имени пользователя (не обязательно нажимая там, где он думает, что нажал!).

Этот параметр всегда должен быть установлен на deny, если только вы не используете фреймы специально, в этом случае он должен быть установлен на same-origin.

Если вы используете фреймы с другим сайтом, вы можете указать здесь белый список другого домена.

Следует также отметить, что этот заголовок заменен директивой CSP frame-ancestors.

Я все еще рекомендую установить ее, чтобы успокоить инструменты, но в будущем она, вероятно, будет постепенно отменена.

X-Frame-Options: deny

Access-Control-Allow-Origin

Указывает браузеру, какой код JavaScript других сайтов может делать запросы к данной странице.

Если вам не нужно настраивать этот параметр, обычно правильным является значение по умолчанию.

Например, если сайт А предоставляет некоторый JavaScript, который хочет сделать запрос к сайту Б, то сайт Б должен предоставить ответ с заголовком, указывающим, что сайту А разрешено делать этот запрос.

Это может быть немного запутанным, поэтому взгляните схему, иллюстрирующую работу этого заголовка:

Access-Control-Allow-Origin: http://www.one.site.com

Убедитесь, что ваши куки отправляются только через HTTPS (зашифрованные), и что они недоступны через JavaScript.

Вы можете отправлять куки по HTTPS, только если ваш сайт также поддерживает HTTPS, что и должно быть.

Вы всегда должны устанавливать следующие флаги:

  • Secure
  • HttpOnly

Пример определения Cookie:

Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

X-XSS-Protection

Этот заголовок указывает браузерам приостановить выполнение обнаруженных атак межсайтового скриптинга.

Обычно его установка не представляет особого риска, но все же его следует протестировать перед внедрением в производство.

X-XSS-Protection: 1; mode=block

Примеры конфигураций веб-сервера

Как правило, лучше всего добавлять заголовки по всему сайту в конфигурации вашего сервера.

Исключением здесь являются файлы cookie, поскольку они часто определяются в самом приложении.

Перед добавлением любых заголовков на ваш сайт я рекомендую сначала проверить обсерваторию или вручную просмотреть заголовки, чтобы увидеть, какие из них уже установлены. Некоторые фреймворки и серверы автоматически устанавливают некоторые из них за вас, поэтому применяйте только те, которые вам нужны или которые вы хотите изменить.

Конфигурация Apache

Пример настройки Apache в .htaccess:

<IfModule mod_headers.c>
    Header set Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';

    Header set X-XSS-Protection: 1; mode=block
    Header set Access-Control-Allow-Origin: http://www.one.site.com
    Header set X-Frame-Options: deny
    Header set X-Content-Type-Options: nosniff
    Header set Strict-Transport-Security: max-age=3600; includeSubDomains

    Header set Cache-Control no-cache
    Header set Expires: 0

    <filesMatch ".(ico|css|js|gif|jpeg|jpg|png|svg|woff|ttf|eot)$">
        Header set Cache-Control "max-age=86400, public"
    </filesMatch>

</IfModule>

Конфигурация Nginx

add_header Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';

add_header X-XSS-Protection: 1; mode=block;
add_header Access-Control-Allow-Origin: http://www.one.site.com;
add_header X-Frame-Options: deny;
add_header X-Content-Type-Options: nosniff;
add_header Strict-Transport-Security: max-age=3600; includeSubDomains;

# Don’t cache by default
add_header Cache-Control no-cache;
add_header Expires: 0;

location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
    try_files $uri @rewriteapp;
    add_header Cache-Control "max-age=86400, public";
}

Настройка заголовков на уровне приложения

Если у вас нет доступа к веб-серверу или у вас сложные требования к настройке заголовков, вы можете захотеть установить их в самом приложении.

Обычно это можно сделать с помощью промежуточного программного обеспечения фреймворка для всего сайта, а также на основе каждого ответа для установки единичных заголовков.

Для краткости в примерах я включил только один заголовок. Добавьте все необходимые с помощью этого метода таким же образом.

Node

app.use(function(req, res, next) {
    res.header('X-XSS-Protection', 1; mode=block);    
    next();
});

PHP

header("X-XSS-Protection: 1; mode=block");

Python / Django

response = HttpResponse()
response["X-XSS-Protection"] = "1; mode=block"

Заключение

Установка заголовков является относительно быстрой и простой задачей.

Вы повысите безопасность вашего сайта в отношении защиты данных, межсайтовых скриптов и клик-джекинга.

см. также:

 

 

 

Добавить комментарий