Рубрики
Без рубрики

Проектирование для реальных HTTPS

Обсуждение того, как разработать HTTP-клиент для лучшей безопасности и пользовательского опыта. Теги с безопасностью, Python, TLS.

Это Cross-Post из моего блога Python ♥ http Отказ Если вы наслаждаетесь своим контентом и хотите, чтобы это рано вы можете Следуй за мной через RSS Отказ

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

И кто может обвинить их, когда у них нет документации или инструментов, чтобы принять правильные решения безопасности в мире, полном наследие программного обеспечения и неправильно настроенных серверов?

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

Что такое https?

HTTPS определен в RFC 2818 как «HTTP над TLS». Если вы не уверены, что такое TLS, вы можете прочитать Это объяснение CloudFlare Отказ

Как пользователи обычно решают проблемы TLS?

Если вы напечатаете « Запрос Сертификат проверки не удалось » в Google Верховный результат, который вы получите, это Ответ в Stackoverflow что (среди хороших советов) упоминает проверить = Ложь который отключает проверку сертификатов.

Это, безусловно, позволит вашему запросу «преуспеть», но также будет жестоко ухудшить безопасность выполнения запросов HTTPS.

Предупреждения против использования verify = false В рамках ответа StackoverFlow может убедить некоторые, Но ищет verify = false ” В коде Python на Github Урожайность> 150 000 результатов.

Наша цель как дизайнер интерфейса – продолжать проверку!

Какие проблемы имеют опыт пользователей?

Представьте, что вы пытаетесь взаимодействовать с внешним сервисом в качестве части вашей работы через HTTP и, конечно, вы хотите использовать HTTPS, потому что это правильная вещь, чтобы сделать!

Имя хоста веб-сайта – Tribunnews.com который просто так бывает с Будь во время этого письма # 41 самый посещаемый сайт в мире. Вы ожидаете, что они будут иметь правильный TLS Config, верно?

Когда вы делаете запрос HTTPS на сайт, вы получаете эту ошибку:

[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1108)

Теперь без использования Google вы можете выяснить, что означает эта ошибка и что вы должны сделать, чтобы исправить это?

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

После правильной настройки вашего клиента (если вы можете!) Вы делаете еще один запрос, на этот раз получаю это:

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1108)

В этот момент, к сожалению, вам удачи, потому что веб-сайт представляет сертификат с двумя Субъективное значение Записи:

  • * .maintenis.com.
  • maintenis.com

… ни один из которых не соответствует нашему значению целевого сайта Tribunnews.com Отказ

Когда возникает ошибка сертификата Мы не можем быть уверены, что веб-сервер мы говорим, это тот, который мы намерены говорить с , Ну что теперь? Что бы вы сделали в такой ситуации?

Если вы догадались, используя www.tribunnews.com (???) Вы будете правильными! Используя www Подделка дает вам Сайт, который вы хотите со всеми правильными конфигурацией TLS и сертификатами.

Браузеры умны и попробуйте www. Если хост является частным зарегистрированным доменом, и соединение не удается По какой-либо причине, чтобы сайт отлично работает для браузеров, но не работает для наших клиентов HTTP … Какой кошмар!

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

Больше примеров проблем HTTPS

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

Я обнаружил, что вопросы сертификатов, как правило, происходят чаще по сравнению с проблемами протокола TLS, поэтому я сосредоточился на них ниже.

Вот список источников, которые я просматривал, чтобы найти примеры этих вопросов:

Я также управлял рукопожатиями TLS на топ-10000 доменов в Alexa 1 миллион и Сохранял результаты всех доменов, где рукопожатие TLS не удалось пристроить с Certifi (Общий выбор для библиотек HTTP Python в качестве пакета сертификата CA по умолчанию) и со всеми TLS 1.2+ и всеми шифрами.

Все эти ниже проблемы могут быть найдены не реже одного раза в топ-10 000 доменов.

Сертификат не имеет субъекта, только commentname

Commonname был устарел более 19 лет назад в RFC 2818 Отказ Вот …| Точный язык:

If a subjectAltName extension of type dNSName is 
present, that MUST be used as the identity. Otherwise,
the (most specific) Common Name field in the Subject
field of the certificate MUST be used. Although the
use of the Common Name is existing practice, it is
deprecated and Certification Authorities are encouraged
to use the dNSName instead.

Что к сожалению говорит, что Commonname должен быть использован, если там являются не Субъективное значение dnsname Записи. Это значит, что это полностью Действителен для CAS, чтобы держать мкинтные сертификаты с общими именами.

Это означает, что мы, вероятно, должны поддерживать способ проверки Сертификаты через распространенное имя на данный момент.

К счастью, браузеры и MacOS заводят мир стандартов вперед, удаляя поддержку для общего имени. MacOS отбросил поддержку общего имени в iOS 13/MacOS 10.15 :

TLS server certificates must present the DNS name of
the server in the Subject Alternative Name extension
of the certificate. DNS names in the CommonName of a
certificate are no longer trusted.

Ничего подобного Вашему сайту не работает на Chrome, Firefox, MacOS и iPhone, чтобы сделать бизнес хочется обновить свой сертификат.

Сертификат самостоятельно подписан

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

В этом случае, особенно когда сертификат доступен для пользователь и может быть проверено локально, Сертификат Pinning Решает эту проблему! Сертификат Pinning – это то, где вам жесткий код подпись или отпечаток отпечатки сертификата, который вы ожидаете, чтобы быть представлены в рукопожатии и если вы получаете сертификат с тем же Отпечаток пальца, затем сертификат автоматически доверяется.

Использование сертификата Pinning является формой «Доверие первого использования» который почти такой же безопасный, как проверка сертификата с использованием CKI и CA Certs За исключением самого первого рукопожатия TLS, где вы делаете первое «доверие» решения самостоятельно.

( Примечание: Подписи сертификата/отпечатки пальцев различны от отпечаток сертификатов. Первый используется для криптографических причин, второй только для ссылки.)

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

Сертификат Pinning в настоящее время поддерживается Urllib3. и AioHTTP Отказ Запросы не предоставляют способ втабочно проверить сертификат через отпечаток пальца.

Клиентские библиотеки должны использовать только Sha256 или сильнее, потому что MD5 небезопасно и Sha1 на краю небезопасности.

Клиентские библиотеки также должны обеспечить, чтобы пользователи знали о подводных камнях и опасностях, связанные с обновлением отпечатков пальцев сертификата или использование закрепления сертификатов с сертификатами, которые могут заменять часто измениться, такие как сертификаты, которые недолговечны (~ менее 6 месяцев срок действия).

Сертификат субъекты или Commance не соответствует хосту

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

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

Я видел, что эта ошибка придумала, где служба имела имя хоста Unicode, закодированное в сертификате с IDNA 2003, потому что он содержал Emoji (который недействителен в IDNA 2008), но Urllib3 больше не поддерживает IDNA 2003 из-за проблем с анализом безопасности Отказ

WhatWG-URL рекомендует отступить на IDNA 2003, но это требует много внимания, чтобы уменьшить все вопросы безопасности, связанные с использованием кодирования в пределах URL.

Рекомендации по библиотекам клиента HTTP

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

Вот список элементов, которые я думаю, приведет к такому интерфейсу:

Укажите современную конфигурацию TLS по умолчанию

90% + пользователи будут использовать эти значения по умолчанию, поэтому вы хотите, чтобы они были лучшими, они могут разумно быть.

На момент написания это означает:

Вот как настроить выше в Python через SSL. SSLContext :

import ssl
import certifi

ctx = ssl.SSLContext(ssl.PROTOCOL_TLS)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(certifi.where())
ctx.options |= (
    ssl.OP_NO_SSLv2 |
    ssl.OP_NO_SSLv3 |
    ssl.OP_NO_TLSv1 |
    ssl.OP_NO_TLSv1_1 |
    ssl.OP_NO_COMPRESSION
)
ctx.set_ciphers(":".join([
    "ECDHE+AESGCM",
    "ECDHE+CHACHA20",
    "DHE+AESGCM",
    "DHE+CHACHA20"
]))

Не позволяйте пользователям отключить проверку сертификата

Особенно для доменов HSTS, где это требуется, чтобы быть совместимым с RFC 6797. . Возможность отключить проверку сертификата результатов небезопасности программное обеспечение. Использование SERT Pinning является более безопасной альтернативой для отключения проверки.

Предоставьте эти функции для настройки TLS

  • Минимальная и максимальная поддерживаемая версия TLS. Рекомендуйте сильно, что пользователи не устанавливают максимальную версию Если они не нацеливаются на одну конкретную версию на одном сервисе.

  • TLS CITHERS должен быть добавлен/удален в зависимости от Минимальная и максимальная версия TLS. Я не думаю, прямой Доступ к настройке шифров должен быть необходим, но сделать Уверен, что вы охватываете все общие шифры и ключевые обмены. Посмотрите, что Firefox использует как их по умолчанию для примера.

  • Интерфейс для обеспечения предварительно настроенного SSLContext Необязательно, На мой взгляд, если интерфейс для упаковки TLS достаточно хорош, обеспечивая Интерфейс для SSLContext Допускается только для отключения функций безопасности.

  • Способность указать сервисный сертификат не по умолчанию или каталог сертификатов для проверки. К сожалению, оптимально поддерживать как «добавка» метод и метод «замены».

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

  • Заменить полезно, когда вы хотите использовать единственный сертификат Для запросов вы делаете и не хотите случайно Доверьте себе услугу за пределами этого трастового магазина.

Я бы сказал, что «аддитивная» корпус является более распространенным с типичными пользователями, но поддерживает оба использования в использовании. Мне нужно сделать больше думать об этом о том, какой будет выглядеть правильный интерфейс.

Поддержка сертификата Pinning как средство проверки

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

Рекомендовать решения для местного тестирования

Для местного тестирования рекомендуют пользователи использовать Поверьте мне или Mkcert генерировать реальные Сертификаты, так что HTTPS и TLS функционируют одинаково локально Как они бы в реальном мире. Это удаляет необходимость отключения проверки во время тестирования или использования закрепления на самозагоревшем сертификате.

Обеспечить лучшие сообщения об ошибках и документацию

Сообщения об ошибках должны содержать всю информацию Им нужно вносить правильные решения безопасности. Это включает в себя информацию из сертификата. Это может потребовать, чтобы вы использовали getpeercert (binary_form = true) и разбираться с библиотекой, такой как ASN1CRYPTO Потому что Python не дает вам приятных анализируемых сертификатов, если только CERT Проверка включена.

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

Разрешить настройку TLS через переменные среды

Обычно клиенты HTTP похоронены слой или более глубоко в использовании библиотеки или используемого инструмента и могут иногда не предоставлять средства для правильной настройки библиотеки клиента HTTP. Разрешение переменных среды для настройки библиотеки исправляет эту проблему для пользователей.

У вас есть сценарий, где вышеизложенное не работает хорошо, или вы хотите Чтобы обсудить эту тему больше? Я хотел бы услышать об этом, пожалуйста, дайте мне знать по Помещая меня Twitter Отказ

Оригинал: “https://dev.to/sethmlarson/designing-for-real-world-https-48g1”