Хабрахабр

[Перевод] Web Security: введение в HTTP

HTTP — вещь прекрасная: протокол, который просуществовал более 20 лет без особых изменений.

image

Это вторая часть серии по веб-безопасности: первая часть была «Как работают браузеры».

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

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

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

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

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

Обзор

Как мы уже видели, HTTP следует модели запроса/ответа, когда клиент, подключенный к серверу, отправляет запрос, а сервер отвечает на него.

HTTP-сообщение (запрос или ответ) состоит из нескольких частей:

  • «first line» (первая строка)
  • headers (заголовки запроса)
  • body (тело запроса)

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

1 GET /players/lebron-james HTTP/1.

1 — ничего сложного для понимания. В этом случае клиент пытается получить ресурс (GET) по адресу /Players/Lebron-James через версию протокола 1.

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

1
Host: nba.com
Accept: */*
Coolness: 9000
GET /players/lebron-james HTTP/1.

Например, в этом запросе клиент добавил к запросу 3 дополнительных заголовка: Host, Accept и Coolness.

Подожди, Coolness?!?!

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

Если бы вам пришлось переименовать заголовок Cache-Control в Awesome-Cache-Control, прокси не имели бы представления о том, как кэшировать ответ, так как они не созданы для соответствия спецификации, которую вы только что придумали. Cache-Control — это, например, заголовок, используемый для определения того, является ли (и каким образом) ответ кешируемым: большинство прокси и обратных прокси понимают его, следуя спецификации HTTP до буквы.

Однако иногда имеет смысл включить в сообщение «пользовательский» заголовок, так как вы можете добавить метаданные, которые на самом деле не являются частью спецификации HTTP: сервер может решить включить техническую информацию в свой ответ, чтобы клиент мог одновременно выполнять запросы и получать важную информацию о состоянии сервера, который возвращает ответ:

...
X-Cpu-Usage: 40%
X-Memory-Available: 1%
...

Заголовки X-Forwarded-For и X-Forwarded-Proto являются примерами пользовательских заголовков, которые широко используются и понимаются балансировщиками нагрузки и прокси-серверами, даже если они не являются частью стандарта HTTP. При использовании пользовательских заголовков всегда предпочтительно ставить перед ними префикс с ключом, чтобы они не конфликтовали с другими заголовками, которые могут стать стандартом в будущем: исторически это работало хорошо, пока все не начали использовать «нестандартные» префиксы X что, в свою очередь, стало нормой.

Если вам нужно добавить собственный настраиваемый заголовок, в настоящее время обычно лучше использовать фирменный префикс, такой как Acme-Custom-Header или A-Custom-Header.

После заголовков запрос может содержать тело, которое отделено от заголовков пустой строкой:

1
Host: nba.com
Accept: */*
Coolness: 9000
POST /players/lebron-james/comments HTTP/1.

Best Player Ever

Обратите внимание, что тело является полностью необязательным и, в большинстве случаев, оно используется только тогда, когда мы хотим отправить данные на сервер, поэтому в приведенном выше примере используется метод POST. Наш запрос завершен: первая строка (информация о местоположении и протоколе), заголовки и тело.

Ответ сильно не имеет различий:

1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=3600
HTTP/1.

Далее следуют заголовки и, если требуется, разрыв строки, за которым следует тело. Первая информация, которая присылается в ответе, — это версия протокола, которую он использует, вместе со статусом этого ответа.

д.), Но основная структура не сильно изменилась (первая строка, заголовки и тело). Как уже упоминалось, протокол подвергся многочисленным пересмотрам и со временем добавились новые функции (новые заголовки, коды состояния и т. Что действительно изменилось, так это то, как клиенты и серверы обмениваются этими сообщениями — давайте рассмотрим это подробнее.

HTTP vs HTTPS vs H2

В HTTP произошли 2 значительных семантических изменения: HTTP / 1.0 и HTTP / 1.1.

«Где HTTPS и HTTP2?», Спросите вы.

HTTPS и HTTP2 (сокращенно H2) — это больше технических изменений, поскольку они представили новые способы доставки сообщений через Интернет, без существенного влияния на семантику протокола.

Пока HTTPS был нацелен на повышение безопасности протокола HTTP, H2 был нацелен на обеспечение высокой скорости. HTTPS является «безопасным» расширением HTTP и включает установление общего секретного ключа между клиентом и сервером, гарантируя, что мы общаемся с нужной стороной, и шифруем сообщения, которые обмениваются общим секретным ключом (подробнее об этом позже).

1. H2 использует двоичные, а не текстовые сообщения, поддерживает мультиплексирование, использует алгоритм HPACK для сжатия заголовков…… Короче говоря, H2 повышает производительность по HTTP/1.

1. Владельцы веб-сайтов неохотно переходили на HTTPS, так как это включало дополнительные обходы между клиентом и сервером (как уже упоминалось, необходимо установить общий секретный ключ между двумя сторонами), тем самым замедляя работу пользователя: с H2, который шифруется по умолчанию оправданий больше нет, так как такие функции, как мультиплексирование и server push, делают его лучше, чем простой HTTP/1.

HTTPS

HTTPS (HTTP Secure) позволяет клиентам и серверам безопасно общаться через TLS (Transport Layer Security), преемник SSL (Secure Socket Layer).

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

Теперь вы столкнулись с двумя проблемами:

  • аутентификация (authentication) того, что вы действительно разговариваете со своей второй половинкой, поскольку это может быть кто-то, притворяющийся ей
  • шифрование (encryption): передача пароля так, чтобы ваши коллеги не смогли его понять и записать

Это именно та проблема, которую HTTPS пытается решить. Что вы будете делать?

Возвращаясь к нашей аналогии, вы можете просто попросить свою вторую половинку сказать ваш номер социального страхования. Чтобы проверить, с кем вы разговариваете, HTTPS использует Public Key Certificates(сертификаты открытых ключей), которые представляют собой не что иное, как сертификаты, указывающие личность конкретного сервера: когда вы подключаетесь через HTTPS к IP-адресу, сервер за этим адресом представляет вам его сертификат для вас, чтобы подтвердить свою личность. Как только вы убедитесь, что номер правильный, вы получаете дополнительный уровень доверия.

Как мы проверим личность звонящего? Это, однако, не мешает «злоумышленникам» узнать номер социального страхования жертвы, украсть смартфон вашей второй половинки и позвонить вам.

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

В терминах HTTPS ваша мама называется CA, сокращение от Certificate Authority: работа CA заключается в проверке личности конкретного сервера и выдаче сертификата с собственной цифровой подписью: это означает, что при подключении к определенному домену я получу не сертификат, сгенерированный владельцем домена (так называемый самоподписанный сертификат), а CA.

После завершения процесса проверки он выдаст сертификат, который затем можно установить на веб-серверы. Задача CA состоит в том, что они проверяют подлинность домена и выдают сертификат соответствующим образом: когда вы «заказываете» сертификат (обычно называемый SSL-сертификатом, хотя в настоящее время вместо него используется TLS — названия действительно прилипают!), CA могут позвонить вам или попросить изменить настройку DNS, чтобы убедиться, что вы контролируете данный домен.

Если сертификат не подписан доверенным органом, браузер отобразит большое информационное предупреждение для пользователей: Затем клиенты, такие как браузеры, будут подключаться к вашим серверам и получать этот сертификат, чтобы они могли проверить его подлинность: браузеры имеют своего рода «отношения» с CA, в том смысле, что они отслеживают список доверенных доменов в CA чтобы убедиться, что сертификат действительно заслуживает доверия.

image

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

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

image

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

Это включает в себя использование математики. Вместо этого используются вариации протокола обмена ключами Диффи-Хеллмана, которые гарантируют, что стороны без предварительного знания устанавливают общий секретный ключ, и никто другой не сможет его «украсть».

image

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

Кроме того, в «Девяти алгоритмах, которые изменили будущее» есть удивительная глава, в которой объясняется шифрование с открытым ключом, и я горячо рекомендую его фанатам компьютерных наук, интересующимся оригинальными алгоритмами. Для получения дополнительной информации о HTTPS и Diffie-Hellman я бы порекомендовал прочитать «Как HTTPS защищает соединения» Хартли Броди и «Как HTTPS на самом деле работает?» Роберта Хитона.

HTTPS везде

Все еще решаете, должны ли вы поддерживать HTTPS на вашем сайте? У меня для вас плохие новости: браузеры начали защищать пользователей от веб-сайтов, не поддерживающих HTTPS, для того, чтобы «заставить» веб-разработчиков предоставлять полностью зашифрованные возможности просмотра.

За девизом «HTTPS везде» браузеры начали выступать против незашифрованных соединений — Google был первым поставщиком браузеров, который дал веб-разработчикам крайний срок, объявив, что начиная с Chrome 68 (июль 2018 года) он будет отмечать веб-сайты HTTP как «небезопасные»:

image

Еще более тревожным для веб-сайтов, не использующих преимущества HTTPS, является тот факт, что, как только пользователь вводит что-либо на веб-странице, метка «Небезопасно» становится красной — этот шаг должен побудить пользователей дважды подумать, прежде чем обмениваться данными с веб-сайтами, которые не поддерживает HTTPS.

image

Сравните это с тем, как выглядит сайт, работающий по HTTPS и имеющий действующий сертификат:

image

В те времена, когда H2 не было реальностью, имело бы смысл придерживаться незашифрованного, простого HTTP-трафика. Теоретически, веб-сайт не должен быть безопасным, но на практике это отпугивает пользователей — и это справедливо. Присоединяйтесь к движению “HTTPS везде” и помогите сделать Интернет более безопасным местом для серфинга. В настоящее время практически нет причин для этого.

GET vs POST

Как мы видели ранее, HTTP-запрос начинается со своеобразной “первой строки”:

Прежде всего, клиент сообщает серверу, какие методы он использует для выполнения запроса: базовые HTTP-методы включают GET, POST, PUT и DELETE, но список можно продолжить с менее распространенными (но все еще стандартными) методами, такими как TRACE, OPTIONS, или HEAD.

Теоретически, ни один метод не безопаснее других; на практике все не так просто.

Другое отличие заключается в побочных эффектах, которые несут эти методы: GET — идемпотентный метод, означающий, что независимо от того, сколько запросов вы отправите, вы не будете изменять состояние веб-сервера. GET-запросы обычно не содержат тела, поэтому параметры включаются в URL (например, www.example.com/articles?article_id=1), тогда как POST-запросы обычно используются для отправки («публикации») данных, которые включены в тело. Вместо этого POST не является идемпотентным: для каждого отправляемого вами запроса вы можете изменять состояние сервера (подумайте, например, о размещении нового платежа — теперь вы, вероятно, понимаете, почему сайты просят вас не обновлять страницу при выполнении сделки).

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

168. 192. 1 - [192. 99. 99. 168. 1" 200 525 "-" "Mozilla/5. 1] - - [29/Jul/2018:00:39:47 +0000] "GET /?token=1234 HTTP/1. 36 (KHTML, like Gecko) Chrome/65. 0 (X11; Linux x86_64) AppleWebKit/537. 3325. 0. 36" 404 0. 181 Safari/537. 17. 002 [example-local] 172. 8:9090 525 0. 0. 168. 002 200
192. 1 - [192. 99. 99. 168. 1" 200 525 "-" "Mozilla/5. 1] - - [29/Jul/2018:00:40:47 +0000] "GET / HTTP/1. 36 (KHTML, like Gecko) Chrome/65. 0 (X11; Linux x86_64) AppleWebKit/537. 3325. 0. 36" 393 0. 181 Safari/537. 17. 004 [example-local] 172. 8:9090 525 0. 0. 168. 004 200
192. 1 - [192. 99. 99. 168. 1" 201 23 "http://example.local/" "Mozilla/5. 1] - - [29/Jul/2018:00:41:34 +0000] "PUT /users HTTP/1. 36 (KHTML, like Gecko) Chrome/65. 0 (X11; Linux x86_64) AppleWebKit/537. 3325. 0. 36" 4878 0. 181 Safari/537. 17. 016 [example-local] 172. 8:9090 23 0. 0. 016 201

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

Отсюда мы можем вывести, что POST (и аналогичные неидемпотентные методы) безопаснее, чем GET, даже если это больше зависит от того, как данные отправляются при использовании определенного метода, а не от того, что конкретный метод по сути более безопасен, чем другие: если бы вы включили конфиденциальную информацию в тело запроса GET, то у вас не возникло бы больше проблем, чем при использовании POST, даже если такой подход был бы сочтен необычным. Веб-серверы не журнализируют HTTP-заголовки и тела, так как сохраняемые данные будут слишком объемными — именно поэтому отправка информации через тело запроса, а не по URL-адресу, как правило, безопаснее.

Мы верим в заголовки HTTP

В этой статье мы рассмотрели HTTP, его развитие и то, как его безопасное расширение объединяет аутентификацию и шифрование, чтобы позволить клиентам и серверам обмениваться данными через безопасный канал: это не все, что HTTP может предложить с точки зрения безопасности.
Перевод выполнен при поддержке компании EDISON Software, которая профессионально занимается безопасностью, а так же разрабатывает системы электронной медицинской проверки.

Теги
Показать больше

Похожие статьи

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть