Что каждый разработчик должен знать о https

Дабы не забыть то, что прошел на pluralsight, зафиксирую основные моменты в статье (сразу извиняюсь за орфографию, пишу наскоро).

HyperText Transfer Protocol Secure — расширение протокола HTTP для поддержки шифрования в целях повышения безопасности. Данные в протоколе HTTPS передаются поверх криптографических протоколов TLS или устаревшего в 2015 году SSL. В отличие от HTTP с TCP-портом 80, для HTTPS по умолчанию используется TCP-порт 443

Зачем вообще нужен https

Как минимум позволяется защитить ваше приложение от атак Man in the middle. Когда например вы подключаетесь к бесплатному wi-fi в кафе и если у вас обычное http соединение, то кто нибудь, имеющий доступ к роутеру может читать ваши данные, либо подменять ответ от сервера.

Так же помогает защититься от подмен DNS и уменьшить вероятность фишинга и кражу cookies.

Есть заблуждения, которые останавливают вас от использования https:

  • сложно
  • дорого
  • ухудшает перформанс
  • совместимость

CA

СА (certificate authority) - сертификат, которым подтвержается подтвержается домен. Его можно посмотреть во вкладке security в панели разработчика. Браузер проверяет матчится ли этот сертификат с вашим локальным списком доверенных сертификатов.

В винде его можно посмотреть через Window + R -> certmgr.msc
Его используют все браузеры, кроме Firefox.

У FireFox свой лист сертификатов, который можно посмотреть в менеджере сертификатов.

SSL vs TLS

SSL - Secure Socket Layer
Закончил свое существование в 2014 в результате POODLE attack. Ныне не используется.
TLS - Transport Secure Layer. Разработан в 1999 как апгрейд для SSL.
Все по прежнему называют его SSL.

TLS Hadshake

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

Затем клиент отправляет Key exchange зашифрованный публичным ключом, а сервер отвечает finished ответом - значит соединение установлено.

Но как быть при локальной разработке?

Можно сделать свой сертификат для локальной разработки при помощи Powershall в Windows и поместить его на сервак.

New-SelfsignedCertificate -certstorelocation cert:\localmachine\my -dnsname example.name123.com

Преобразуем пароль для сертификата в зашифрованную строку
$pwd = Convert-SecureString -String "z34wdf42ew" -Force -AsPlainText

А потом экспортируем сертификат
Export-PfxCertificate -cert cert:\localmachine\my\{hash} -FilePath c:\Cert\cert.pfx -Password $pwd - где {hash} хеш от предыдущей команды

Готово!

Мониторинг https траффика

Fiddler может отлавливать https трафик, если включить нужную опцию в настройках, при этом он создаст свой сертификат, который фактически будет имитировать man in the middle, потому что заменит остальные сертификаты на свой.


https://badssl.com позволяет потестировать плохие сертификаты и посмотреть что и как работает с ними.

Работа с запросами http/https

Мы можем заредиректить юзера после первого http реквеста на https схему, но уже 1 небезопасный реквест может доставить проблем (тот же man in the middle)

Strict-transport-security заголовок - появляется после первого редиректа и после этого браузер всегда ходит по https для этого сайта.
Strict-transport-security: max-age=2592000

Но все равно остается потенциальная возможность для опасности на первом http запросе.

Max-age выставить 1 год, preload - позволяет захардкодить в браузеры то, что ваш сайт юзает https (hsts preload list)

Strict-transport-security: max-age=31536000; includeSubDomains; preload

При этом нужно добавить сайт в список предзагружаемых по https сайтов на
https://hstspreload.org

Проблема mixed content - згрузка некоторых ресурсов идет по http схеме

Решение для загрузки ресурсов:

  • Картинки загружать по относительному пути - без хттп
  • Загрузка ютуба можно делать без протокола //www.youtube….

На всякий случай можно добавлять scp мета тег с content=‘upgrade-insecure-request’, который говорит, что нужно делать с контентом который загружается несекьюрно. Увы этот тег поддерживается всего 60% браузеров.

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-request">

Можно добавить вместо этого block-insecure-content и он заблокирует все реквесты. На сайт не подгрузятся некоторые ресурсы, но зато не будет ворнингов и будет зеленый значек в адресной строке.

<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">

Кстати при https запросах можно выставлять secure куки (как и несекьюрные). И только при https запросах будут передаваться secure куки.

Развенчиваем мифы

https медленный


HTTPS использует по капотом HTTP/2, поэтому может делать мультизагрузку данных параллельно

Несовместимость

Множество сервисов уже поддеривают https, а если вы встраиваете в сайт запросы к сервисам которые используют http, эту проблему можно решить теми же csp заголовками.

Сложности с сертификатом, затраты на выпуск

Let's Encrypt позволяет бесплатно выпустить сертификат. А certBot позволяет автоматически выпускать и устанавливать сертификат на платформе вашего хостинга.

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

Прямо сейчас я за 5 минут настроил https для этого блога, включая регистрацию на Cloudflare.

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

SNI - Server Name Idndication - позволяет иметь множество сертификатов на одном ip адресе
SAN - Subject Alternative Name - возможность иметь несколько доменных имен на одном сертификате
PFS - Perfect Forward Securecy - защищает сессии, если приватный ключ был скомпроментирован
DNSSEC - Domain Name System Security Extention - защита от подмены DNS записей
DANE - DNS Based Authentication of Named Entities - возможность указать сертификаты на уровне DNS
CAA - Certificate Authority Authorization - Возможноть указывать возможные Certificate Authority на DNS уровне
CRL - Certificate Revocation List - список аннулированных сертификатов
OCSP - Online Certificate Status Protocol - список аннулированных сертификатов (альтернатива CRL)
PKP - Public Key Pinning - Предопределенный список ключей который клиент может принять при TLS Handshake

Когда клиент коннектится и получает сертфикат, он проверяет его на корректность. Но что если он был выпущен обманным путем?
Для этого есть HTTP PKP - определение публичных ключей которые соответствуют этому домену.
Есть список аттрибутов HPKP:

  • max age - промежуток времени, при котором клиент использует ключ. Если в этот период будет выпущен новый сертификат - клиент не будет ему доверять
  • subdomains - рспространяется ли сертификат на поддомен
  • report-uri - возможность репортать о нарушениях на определенный url в случаях аттак и тп

HPKP - это респонз заголовок

public-key-pins:
pin-sha256="4rwe32" хеши публичных ключей
max-age=""
includeSubdomain
report-uri="http...."

https://www.ssllabs.com/ssltest - сайт, на котором можно просмотреть инфу о сертификате, просто указав url.

Расширенная валидация

Сайт вверху - фишинговый сайт. Но у него есть SSL сертификат (потому что его несложно получить), и у людей будет довере к нему.
Официальный сайт paypal прошел процедуру подтверждения и имеет некоторые отличия в адресной строке

Некоторые дополнительные бенефиты от HTTPS:

  • немного улучшает SEO
  • не передает допольнительные данные, если вы переходите на http сайт с https сайта (например referrer заголовок)
  • использование Brotli сжатия

Кстати, завел личный блог Sleepless Tech в Telegram про разработку и DIY, заходите!

И присоединяйтесь к каналам FrontEndDev и Web Stack в Telegram, чтобы не пропустить самое интересное из мира Web!