Защита от злоумышленников с помощью HTTPS и HTTP Strict Transport Security

Учитывая объем персональных данных, которые передаются по интернету, шифрование – это то, что мы не можем и не должны игнорировать. Современные браузеры предлагают несколько механизмов, которые можно использовать для обеспечения безопасности данных пользователей при передаче. Два наиболее важных из них – это безопасные файлы cookie и Strict Transport Security. Они позволяют легко защитить пользователей, переводя их подключения на HTTPS и гарантируя, что пользовательские данные никогда не будут отправлены в открытом виде.

Почему стоит публиковать Shorts? Рассмотрим пример.

Передачу веб-страницы по незашифрованному HTTP-соединению можно сравнить с отправкой письма в незапечатанном конверте через первого встречного, который идет в сторону почты. Если вам повезет, она может сама донести его до места назначения или передать следующему человеку, который идет в нужном направлении. Этот человек может сделать то же самое, и так далее.

Большинство незнакомцев в этой импровизированной цепочке заслуживают доверия и никогда не заглянут в ваше открытое письмо и не изменят его. Однако чем больше людей передают письмо, тем больше у них возможностей прочитать его. В итоге получатель, скорее всего, получит что-то по почте, но будет ли это тем же самым, что вы отправили, – большой вопрос. Может, тебе стоило запечатать тот конверт…

Посредники

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

Вы можете увидеть эти переходы в действии с помощью traceroute. Маршрут от моего компьютера до HTML5Rocks выглядит примерно так:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

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

Хуже всего то, что такой перехват практически невозможно обнаружить. Вредоносно измененный HTTP-ответ выглядит точно так же, как и действительный ответ, поскольку не существует механизма, который позволил бы вам убедиться, что полученные данные _точно_ соответствуют отправленным. Если кто-то решит перевернуть мой интернет вверх дном ради забавы, то мне, скорее всего, не повезет.

Это защищенная линия?

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

В омнибоксе Chrome можно найти подробную информацию о статусе подключения.
В омнибоксе Chrome можно найти подробную информацию о статусе подключения.

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

Таким образом, HTTPS дает вам некоторую уверенность в том, что вы общаетесь с сервером, с которым, по вашему мнению, вы общаетесь, и что никто другой не подслушивает и не подкручивает биты по проводам. Такое шифрование – обязательное условие безопасности в интернете. Если ваше приложение не использует HTTPS, оно уязвимо для атак. Изменить На сайте Ars Technica есть отличное руководство по получению и установке бесплатного сертификата. Рекомендую ознакомиться с ним, чтобы узнать технические подробности. Конфигурация будет отличаться в зависимости от поставщика и сервера, но процесс запроса сертификата везде одинаков.

Безопасность по умолчанию

После того как вы запросите и установите сертификат, убедитесь, что ваши пользователи могут воспользоваться преимуществами вашей работы: переведите существующих пользователей на HTTPS-соединения с помощью HTTP-переадресации и убедитесь, что файлы cookie доставляются только по защищенным соединениям.

Сюда, пожалуйста

Когда пользователь переходит на страницу http://example.com/, перенаправьте его на страницу https://example.com/, отправив ответ 301 Moved Permanently с соответствующим заголовком Location:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

Такую переадресацию легко настроить на серверах Apache или Nginx. Например, конфигурация Nginx, которая перенаправляет с http://example.com/ на https://example.com/, выглядит следующим образом:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

Файлы cookie позволяют нам обеспечивать пользователям удобный вход в систему по протоколу HTTP без сохранения состояния. Данные, хранящиеся в файлах cookie, включая конфиденциальную информацию, например идентификаторы сеансов, отправляются с каждым запросом, что позволяет серверу понять, какому пользователю он отвечает в данный момент. После того как мы убедились, что пользователи заходят на наш сайт по протоколу HTTPS, мы также должны убедиться, что конфиденциальные данные, хранящиеся в файлах cookie, передаются только по защищенному соединению и никогда не отправляются в открытом виде.

Обычно для этого используется HTTP-заголовок, который выглядит примерно так:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

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

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

Файлы cookie, для которых задано ключевое слово secure, никогда не будут передаваться по протоколу HTTP.

Закрытие открытого окна

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

Чтобы снизить риск такой атаки, можно настроить браузер так, чтобы он принудительно использовал HTTP Strict Transport Security (HSTS). Отправка HTTP-заголовка Strict-Transport-Security указывает браузеру, что перенаправление с HTTP на HTTPS должно выполняться на стороне клиента, без обращения к сети. Это также позволяет повысить производительность, поскольку лучший запрос – это тот, который не нужно выполнять.

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Браузеры, поддерживающие этот заголовок (в настоящее время это Firefox, Chrome и Opera), будут знать, что сайт запрашивает доступ только по протоколу HTTPS. Это означает, что независимо от того, как пользователь переходит на сайт, он будет посещать его по протоколу HTTPS. Даже если она введет в браузере http://example.com/, она все равно попадет на HTTPS-версию сайта, не подключаясь по протоколу HTTP. Более того, если браузер обнаружит недействительный сертификат (что может указывать на попытку подмены идентификационных данных сервера), пользователи не смогут продолжить работу по протоколу HTTP. Это отличная мера безопасности.

Браузер прекратит использовать HSTS для сервера через max-age секунд (в этом примере – примерно через месяц). Установите достаточно большое значение.

Чтобы защитить все субдомены источника, добавьте в заголовок директиву includeSubDomains:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Безопасность в пути

HTTPS – единственный способ быть уверенным, что отправленные вами данные дойдут до получателя в целости и сохранности. Вам следует настроить безопасные соединения для своих сайтов и приложений уже сегодня. Это довольно простой процесс, который поможет обеспечить безопасность данных ваших клиентов. После того как вы настроили зашифрованный канал, следует прозрачно перенаправлять пользователей на это защищенное соединение независимо от того, как они переходят на ваш сайт. Для этого отправляйте HTTP-ответ 301. Затем убедитесь, что вся конфиденциальная информация о сеансах пользователей передается только по этому защищенному соединению. Для этого при настройке файлов cookie добавьте ключевое слово secure. После этого убедитесь, что пользователи не столкнутся с проблемами. Для этого настройте отправку заголовка Strict-Transport-Security.

Настроить HTTPS несложно, а преимуществ у этого протокола множество. Это стоит затраченных усилий.

Ресурсы

  • StartSSL предлагает бесплатные сертификаты для подтвержденных доменов. Бесплатно – это всегда хорошо. Переход на более высокие уровни проверки, конечно, возможен и стоит разумных денег.
  • Тест SSL-сервера. Настроив HTTPS для своих серверов, убедитесь, что все сделано правильно, запустив тест сервера SSL Labs. Вы получите подробный отчет, который покажет, действительно ли все работает.
  • В статье Securing your Web Server with SSL/TLS (Защита веб-сервера с помощью SSL/TLS) на сайте Ars Technica подробно описаны технические аспекты настройки сервера.
  • Рекомендуем ознакомиться со спецификацией HTTP Strict Transport Security (RFC6797), в которой содержится вся техническая информация о заголовке Strict-Transport-Security.
  • Когда вы освоитесь, можно будет сделать так, чтобы ваш сайт был доступен только по определенному набору сертификатов. В IETF ведется работа, которая позволит вам делать именно это с помощью заголовка Public-Key-Pins. Пока это только начало, но идея интересная и за ней стоит следить.