Что каждый разработчик должен знать о 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!