Прямо сейчас у нас есть небольшая проблема, но на мой взгляд, со временем ситуация может только ухудшиться. Всё больше и больше сайтов получают сертификаты — необходимые документы для внедрения HTTPS — но у нас нет механизма для защиты от злоупотреблений.
Сертификаты
Мы сейчас видим настоящую золотую лихорадку вокруг сертификатов, поскольку всё больше сайтов внедряют HTTPS. Кроме очевидных преимуществ безопасности и приватности, есть и другие выгоды от внедрения защищённых соединений, которые я перечислил в статье «Вы всё ещё думаете, что вам не нужен HTTPS?». Обычно именуемые «SSL-сертификаты» или «HTTPS-сертификаты» разлетаются со скоростью, которой мы никогда не видели в истории интернета. Каждый день я исследую сайты из первого миллиона по посещаемости и анализирую различные аспекты их безопасности, а каждые 6 месяцев публикую отчёт. Вы можете изучить эти отчёты здесь, но сейчас посмотрим на темпы внедрения HTTPS.
Процент сайтов из первого миллиона самых популярных сайтов по статистике Alexa, где стоит редирект на версию HTTPS
Мы не просто продолжаем внедрять HTTPS, но скорость внедрения тоже увеличивается. Так выглядит настоящий прогресс. Процесс получения сертификата со временем становится более простым, благодаря великолепному Let's Encrypt, к тому же ещё и сертификаты стали бесплатными. Если вкратце, мы просто отправляем запрос на получение сертификата (Certificate Signing Request, CSR) в центр сертификации (CA), а тот предлагает доказать факт владения доменом. Обычно это делается с помощью изменения записи DNS TXT или размещения специального кода где-нибудь по случайному URL на нашем домене. Как только задание выполнено, CA выдаёт сертификат, и мы можем предъявлять его браузерам и наслаждаться зелёным замком и указанием HTTPS в адресной строке.
Я написал несколько инструкций по этому процессу, в том числе с чего начать, как грамотно обновить и как использовать двойные сертификаты. Это всё здорово, не правда ли? Но в чём проблема? А проблема возникнет тогда, когда всё пойдёт не по плану и у вас случится плохой день.
Нас хакнули
Никто и никогда не хотел бы услышать эти слова, но реальность такова, что нам приходится их слышать чаще, чем хотелось бы. Хакеры могут получить что угодно, когда у них есть доступ к нашему серверу, и часто им нужен секретный ключ. Сертификаты HTTPS — это публичные документы, которые мы отправляем каждому посетителю нашего сайта, но единственная вещь, которая не позволяет другим использовать такой же сертификат — отсутствие нашего секретного ключа. Когда браузер устанавливает защищённое соединение с сайтом, он проверяет, что у сервера есть секретный ключ для используемого сертификата. Вот почему никто не может использовать наш сертификат. Если хакер получает секретный ключ, то ситуация меняется.
Если злоумышленник завладел нашим секретным ключом, то он может выдать себя за нас. Повторим это: кто-то в интернете может доказать, что он — это вы, хотя в реальности он таковым не является. Это реальная проблема, и прежде чем вы подумаете «Со мной такого никогда не произойдёт», вспомните Heartbleed. Этот крошечный баг в библиотеке OpenSSL позволял злоумышленнику украсть ваш секретный ключ, даже если вы соблюдали все меры безопасности. Кроме этого, было бесчисленное множество случаев, когда секретные ключи утекали из-за случайности или небрежности. Реальность такова, что мы можем потерять наш секретный ключ, а когда это случается, нам требуется способ помешать злоумышленнику использовать наш сертификат. Нужно его отозвать.
Отзыв
В случае компрометации мы должны отозвать сертификат, чтобы исключить возможность злоупотреблений. Как только сертификат помечен как отозванный, браузер знает, что ему нельзя доверять, даже если у него не закончился срок действия. Владелец запросил отзыв, и ни один клиент больше не должен принимать этот сертификат.
Как только мы узнаём о факте взлома, мы связываемся с CA и просим отозвать наш сертификат. Нужно доказать факт владения сертификатом, и как только мы сделали это, то CA помечает сертификат как отозванный. Теперь нужен способ сообщить об этом факте каждому клиенту, которому может потребоваться данная информация. Прямо в этот момент браузер, конечно, ничего не знает, и это проблема. Есть два механизма, которые используются для распространения информации: это список отозванных сертификатов (Certificate Revocation List, CRL) и протокол проверки статуса сертификата (Online Certificate Status Protocol, OCSP).
Списки отозванных сертификатов
CRL — действительно очень простая концепция, это просто список всех сертификатов, которые CA пометил как отозванные. Клиент может отправить запрос к серверу CRL и скачать копию списка. Имея копию этого списка, браузер сверяет с ним предъявленный сертификат. Если он там присутствует, то браузер знает, что сертификат недействителен и ему нельзя доверять, он тогда выдаст ошибку и разорвёт соединение. Если сертификата нет в списке, то всё нормально — и браузер продолжит работу.
Проблема CRL в том, что списки содержат много сертификатов от конкретных центров сертификации. Не вдаваясь в излишние детали, они разбиваются на промежуточные сертификаты CA, а центр сертификации может выдавать списки меньшими частями, но проблема остаётся той же. У списка CRL немалый размер. Другая проблема в том, что у клиента нет свежей копии CRL, ему нужно запросить её при первоначальном подключении к сайту, что может сделать всю процедуру заметно медленнее. Всё это выглядит не очень приятно, так что посмотрим на OCSP.
Протокол проверки статуса сертификата
OCSP предлагает намного более красивое решение проблемы и имеет значительное преимущество перед CRL. Здесь мы спрашиваем у CA статус единственного, конкретного сертификата. Это значит, что CA должен вернуть только простой ответ: сертификат либо хороший, либо отозван, и такой ответ гораздо меньше по размеру, чем список CRL. Отлично!
Действительно, OCSP превосходит CRL по скорости получения ответа, но за это преимущество нужно платить (вы тоже ненавидите, когда такое случается?). Цена довольно высока — это ваша приватность… Если подумать о сути запроса OCSP, это очень конкретный запрос на единственный сертификат HTTPS. По сути, происходит утечка информации. Когда вы отправляете запрос OCSP, вы буквально спрашиваете у центра сертификации:
Сертификат для pornhub.com валидный?
Так что это не идеальный сценарий. Вы теперь выдаёте историю посещённых сайтов некоей третьей стороне, о которой даже ничего не знаете, и всё ради HTTPS, который вроде как должен повысить вашу приватность и безопасность. Но погодите, есть ещё кое-что.
Полный сбой
Выше я говорил о CRL и OCSP, двух механизмах проверки сертификатов браузером, и они выглядят таким образом.
После получения сертификата браузер обратится к одному из этих сервисов и отправит запрос для окончательного выяснения статуса сертификата. А что, если у вашего CA плохой день и его инфраструктура в офлайне? Что, если ситуация выглядит так?
Здесь у браузера только два варианта. Он может отказаться принимать сертификат, поскольку не способен проверить его статус. Или взять на себя риск и принять сертификат, не зная его статус, отозван он или нет. У обоих вариантов есть свои преимущества и недостатки. Если браузер откажется принимать сертификат, то каждый раз при уходе инфраструктуры CA в офлайн ваши сайты тоже уходят туда же. Если браузер продолжит принимать сертификаты, то он рискует принять сертификат, который был украден, и подвергает пользователя риску. Это трудный выбор, но прямо сейчас, сегодня, ничего такого на самом деле не происходит…
Частичный сбой
На самом деле сегодня браузеры выполняют так называемую проверку отзыва сертификата с частичным сбоем. То есть браузер попытается проверить статус сертификата, но если ответ не пришёл совсем или не пришёл за короткий промежуток времени, то браузер просто забывает об этом. Ещё хуже, что Chrome даже не пытается проверить сертификат. Да, вы прочитали правильно, Chrome даже не пытается проверить статус сертификата, который ему поступает. Вы можете найти это странным, но я полностью согласен с их подходом и я рад сообщить, что Firefox тоже, вероятно, скоро начнёт работать так же. Позвольте объяснить. Проблема с полным сбоем очевидна: если у CA плохой день, то у нас тоже он будет, вот так мы пришли к логике частичного сбоя. Браузер теперь пытается осуществить проверку сертификата на предмет отзыва, но полностью отказывается от неё, если она занимает слишком много времени или если кажется, что CA ушёл в офлайн. Погодите, какие были последние слова? Проверка сертификата на предмет отзыва отменяется, «если кажется, что CA ушёл в офлайн». Интересно, может ли злоумышленник имитировать такие условия?
Если вы осуществляете атаку MiTM, то вам нужно всего лишь блокировать запрос на проверку сертификата и создать впечатление, что CA не работает. Браузер тогда столкнётся с частичным сбоем проверки и продолжит радостно использовать отозванный сертификат. Если вас никто не атакует, то каждый раз при проверке этого конкретного сертификата вы тратите время и ресурсы на проверку, что сертификат не отозван. И один раз, когда вас атакуют — тот единственный раз, когда вам по-настоящему нужна такая проверка — злоумышленник просто блокирует соединение, и браузер проходит через частичный сбой. Адам Лэнгли из Google лучше всех описал, что такое отзыв сертификата: это ремень безопасности, который защёлкивается в момент аварии, и он прав. Вы каждый день садитесь в машину и пристёгиваете ремень безопасности — и он даёт вам приятное и комфортное ощущение безопасности. А потом в один день что-то идёт не по плану — вы попадаете в аварию, и вот тут вы вылетаете в ветровое стекло. В тот единственный раз, когда он действительно нужен, ремень безопасности вас подводит.
Исправление проблемы
Прямо сейчас в данный конкретный момент времени реальность такова, что мы не можем исправить ситуацию. Впрочем, кое-что можно предпринять и, возможно, в будущем механизм отзыва сертификатов станет по-настоящему надёжным.
Проприетарные механизмы
Если сайт скомпрометирован и злоумышленник получил секретный ключ, то он может подделать этот сайт и причинить некоторый вред. Здесь ничего хорошего, но могло быть и хуже. Что если CA скомпрометирован и злоумышленник получил секретный ключ для промежуточного сертификата? Это было бы катастрофой, потому что тогда злоумышленник может подделать буквально любой сайт, который захочет, подписав собственный сертификат. Поэтому вместо онлайновой проверки промежуточных сертификатов на предмет отзыва у Chrome и Firefox есть собственные механизмы для той же задачи.
В Chrome он называется CRLsets, а в Firefox — OneCRL. Эти механизмы проверяют списки отозванных сертификатов, объединяя доступные CRL и выбирая оттуда сертификаты. Так проверяются особо ценные сертификаты вроде промежуточных, но что насчёт обычных, наших с вами?
OCSP Must-Staple
Чтобы объяснить, что такое OCSP Must-Staple, нужно сначала вкратце разобраться, что такое OCSP Stapling. Я не хочу здесь вдаваться в лишние подробности, вы можете получить всестороннюю информацию из моего блога по OCSP Stapling, но вот суть. OCSP Stapling избавляет браузер от необходимости отправлять запрос OCSP, выдавая ответ OCSP вместе с самим сертификатом. Это называется OCSP Stapling, потому что сервер должен «скрепить» (staple) ответ OCSP с сертификатом и выдать их вместе.
На первый взгляд это кажется немного странным, потому что сервер как будто «сам удостоверяет» собственный сертификат как неотозванный, но всё работает правильно. Ответ OCSP действует только короткий промежуток времени и подписан CA точно так же, как сертификат. Так что если браузер может удостовериться, что сертификат подписан CA, то точно так он может удостовериться, что ответ OCSP тоже подписан этим CA. Это устраняет большую проблему приватности и избавляет клиента от бремени выполнять внешний запрос. Лучший вариант! Но на самом деле не лучший, извините. OCSP Stapling — отличная вещь, и все мы должны поддерживать эту технологию на своих сайтах, но действительно ли мы думаем, что её будет поддерживать злоумышленник? Нет, я так не думаю, конечно же он не будет этого делать. Что нам на самом деле нужно — так это заставить сервер поддерживать OCSP Stapling, и вот для чего нужен OCSP Must-Staple. При запросе нашего сертификата у CA мы просим его установить на нём флаг OCSP Must-Staple. Этот флаг указывает браузеру, что сертификат должен поставляться с откликом OCSP или он будет отвергнут. Установить флаг легко.
После установки этого флага мы должны гарантировать, что используется OCSP Staple, иначе браузер отвергнет сертификат. В случае компрометации, если злоумышленник получит наш ключ, ему также придётся использовать OCSP Staple вместе с нашим сертификатом, а если он не включит OCSP Staple, то ответ OCSP скажет, что сертификат отозван, и браузер его не примет. Тада!
OCSP Expect-Staple
Хотя Must-Staple кажется отличным решением проверки отзыва сертификатом, это не совсем так. На мой взгляд, одной из самых больших проблем является то, что я как оператор сайта не могу точно знать, насколько надёжны метки OCSP Staple и как их принимает клиент. Без включенного OCSP Must-Staple это не является проблемой, но если включить OCSP Must-Staple и мы не уверены в надёжности или правильности OCSP Staple, это проблема для сайта. Чтобы попытаться и получить некую обратную связь о качестве меток OCSP Staple, мы можем активировать функцию под названием OCSP Expect-Staple. Я писал о ней раньше, и вы можете узнать все подробности в блоге OCSP Expect-Staple, но здесь тоже объясню вкратце. Вдобавок к списку предзагрузки HSTS вы запрашиваете браузер прислать отчёт, удовлетворён ли он меткой OCSP Staple. Вы можете собирать отчёты сами или использовать мой сервис report-uri.io, в обоих случаях вы точно узнаете, когда ваш сайт столкнулся с проблемами при работе OCSP Must-Staple. Поскольку использование списка предзагрузки HSTS не настолько очевидно, как мне бы хотелось, я также написал спецификацию для определения нового заголовка безопасности под названием Expect-Staple, чтобы обеспечивать ту же функциональность ценой меньших усилий. Идея в том, что теперь вы можете установить этот заголовок и включить функцию отправки отчётов, которые так нам нужны, ещё до активации Must-Staple. Установка заголовка будет простой, как и всех остальных заголовков безопасности:
Expect-Staple: max-age=31536000; report-uri="https://scotthelme.report-uri.io/r/d/staple"; includeSubDomains; preload
Поддельные сертификаты
Если мы говорим об отзыве сертификатов, то должны рассмотреть тему их подделки. Если некто пытается скомпрометировать CA или как-то ещё получить сертификат, который ему не положен, то как он будет действовать? Если я прямо сейчас взломаю CA и получу сертификат на ваш сайт, то вы не узнаете об этом до тех пор, пока об этом не сообщат в новостях. У вас в компании даже может быть инсайдер, который получит сертификат в обход внутренних процедур, и он будет делать с ним всё что захочет. Нам нужна стопроцентная прозрачность, и скоро мы её получим. Это Certificate Transparency.
Certificate Transparency
CT — новое требование, которое станет обязательным в начале следующего года. Оно предусматривает, что все сертификаты должны заноситься в публичный журнал, чтобы браузер им доверял. Вы можете почитать статью с более подробным описанием CT, но суть в том, что CA заносит все выданные сертификаты в журнал CT.
Эти журналы полностью открыты, и любой может посмотреть их, так что если кто-то получит сертификат на ваш сайт, то вы об этом узнаете. Например, здесь вы можете увидеть все сертификаты, выданные на мой домен, и поискать свой собственный. Есть также сервис CertSpotter от sslmate для той же цели, а я использую инструмент Facebook Certificate Transparency Monitoring, который присылает вам письмо каждый раз, когда выдан сертификат на заданный домен. Стандарт CT — это фантастическая идея, и я не могу дождаться, когда он станет обязательным, но есть одна оговорка. Дело в том, что CT — это только первый шаг. Знать об этих сертификатах хорошо, но у нас по-прежнему остаются все упомянутые проблемы с их отзывом. Тем не менее, мы можем решать только по одной проблеме за раз, и даже самые лучшие в мире механизмы отзыва неэффективны, если мы не знаем, какие сертификаты нужно отзывать. CT по крайней мере даёт нам эту информацию.
Авторизация центров сертификации
Предотвратить выдачу сертификата намного проще, чем пытаться отозвать его, и именно для этого нужна авторизация центров сертификации (CAA). Опять же, подробности есть в статье по ссылке, но вкратце суть в том, что мы можем авторизовать только конкретные центры сертификации выдавать нам сертификаты, в отличие от нынешней ситуации, когда мы не можем указать вообще никаких предпочтений. Авторизация делается так же просто, как создание записи DNS:
scotthelme.co.uk. IN CAA 0 issue "letsencrypt.org"
Хотя авторизация CA — не особенно сильный механизм, и он не способен помочь во всех ситуациях некорректной выдачи сертификатов, но в некоторых случаях он полезен, так что следует заявить о своих предпочтениях, создав запись CAA.
Заключение
В настоящий момент существует реальная проблема, что мы не можем отозвать сертификат, если кто-то получил наш секретный ключ. Только представьте, во что это выльется при раскрытии следующей глобальной уязвимости масштаба Heartbleed! Одна вещь, которую вы можете попытаться сделать — это ограничить размер ущерба от утечки, сократив срок действия своего сертификата. Вместо трёх лет указывайте один год или даже меньше. Let's Encrypt выдаёт только сертификаты, которые действительны всего лишь 90 дней! С сокращением времени жизни вашего сертификата у злоумышленника будет меньше времени для злоупотреблений. Кроме этого мы мало что можем сделать.
Для демонстрации проблемы и того, насколько она реальна, попробуйте зайти на новый поддомен, который я открыл на своём сайте, revoked.scotthelme.co.uk. Как вы вероятно догадываетесь, к этому поддомену прикреплён отозванный сертификат, и вполне вероятно, что он нормально загрузится в вашем браузере. Если нет, если ваш браузер выдаст предупреждение об истёкшем сроке действия, то это значит, что ваш браузер по-прежнему отправляет запросы OCSP и вы только что сообщили в CA о том, что посетили мой сайт. Для доказательства, что такая проверка с мягким сбоем бесполезна, можете добавить в hosts
домен ocsp.int-x3.letsencrypt.org
с IP-адресом 127.0.0.1
или блокировать его каким-нибудь другим способом — и повторить попытку подключения. На этот раз страница нормально загрузится, потому что проверка отозванного сертификата не сработает, а браузер продолжит загружать страницу. Толку от такой проверки…
Я бы хотел закончить статью вопросом: следует ли нам исправлять процедуру отзыва сертификатов? Впрочем, это тема для другой статьи.
Автор: m1rko