Gunicorn: Параметр SSL-шифров по умолчанию отключает самые безопасные шифры.

Созданный на 23 янв. 2019  ·  3Комментарии  ·  Источник: benoitc/gunicorn

Значение по умолчанию для параметра --ciphers - TLSv1 .

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

>>> import ssl
>>> ctx = ssl.SSLContext()
>>> ctx.set_ciphers('TLSv1')
>>> tlsv1 = {c['name'] for c in ctx.get_ciphers()}
>>> ctx.set_ciphers('DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256')  # From OWASP
>>> aplus = {c['name'] for c in ctx.get_ciphers()}
>>> aplus & tlsv1
set()

Это может привести к ошибкам OpenSSL NO_SHARED_CIPHER для клиентов, настроенных с высокими параметрами безопасности.

Одним из решений было бы просто добавить в набор шифров TLSv1.2, изменив значение по умолчанию на строку 'TLSv1:TLSv1.2' . Это добавит совместимости для клиентов, настроенных со строгими параметрами безопасности, без нарушения работы существующих пользователей gunicorn. Однако это оставит в наборе слабые шифры.

Более безопасным вариантом было бы выбрать одну из строк OWASP по умолчанию на основе описанного уровня совместимости. Например, OWASP Cipher String C или C- сохранит широкую совместимость, исключая заведомо слабые шифры.

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

Feedback Requested FeaturSSL

Самый полезный комментарий

Кроме того, Python имеет свой собственный список шифров по умолчанию: он никогда не возвращается к значению по умолчанию OpenSSL (который, по-видимому, равен DEFAULT:!aNULL:!eNULL ). Он доступен как ssl._DEFAULT_CIPHERS хотя это внутреннее / недокументированное, поэтому способ доступа к значениям по умолчанию - никогда не вызывать set_ciphers () в SSLContext.

Для Python 3.6 _DEFAULT_CIPHERS равно

'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES'

В Python 3.7 это

'DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK'

с комментарием «ПО УМОЛЧАНИЮ: список шифров OpenSSL по умолчанию. Начиная с версии 1.0.2, список находится в разумном порядке».

Эти настройки кажутся довольно жесткими и в том же духе, что и OWASP.

Также есть _RESTRICTED_SERVER_CIPHERS который предназначен для использования на серверах (идеально подходит для стрельбы) и более жесткий, чем _DEFAULT_CIPHERS в некоторых версиях Python, но он является внутренним и нигде не используется - но был поддерживается по крайней мере с 3.4.

Таким образом, вариант 3 используется по умолчанию для набора шифров Python по умолчанию.

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

Все 3 Комментарий

Спасибо, что сообщили об этой проблеме. Мы это прекрасно понимаем. Gunicorn какое-то время не вносил существенных изменений в поддержку SSL. См. №1933 и вопросы, связанные с этим обсуждением.

А пока, если теперь есть более разумное значение по умолчанию, когда Gunicorn поддерживает только Python 3.4+, отправьте запрос на перенос, и я буду рад объединить его. Мы также рассматриваем возможность повышения этой минимальной версии выше, поэтому, если есть более высокая минимальная версия Python, которая обеспечит еще более безопасный вариант по умолчанию, разместите эту информацию здесь, чтобы помочь принять это решение до следующего выпуска.

Доступные шифры (и интерпретация аргумента SSLContext.set_ciphers() ) зависят не от версии Python, а от версии OpenSSL / LibreSSL, на основе которой строится Python. В Linux это обычно версия, предоставляемая дистрибутивом.

Если ваш вопрос: «можем ли мы установить более безопасное значение по умолчанию, которое всегда работает в Python 3.4+», то строгий ответ - «нет», потому что это зависит от того, как вы скомпилировали Python. Возможно, удастся скомпилировать недавний Python против очень старого OpenSSL, в котором отсутствуют надежные шифры, поэтому необходимость использования надежных шифров в Gunicorn может означать, что SSL вообще не работает.

Однако я думаю, что мы в значительной степени в безопасности. Python 3.4 был выпущен в 2014 году, а OpenSSL 1.0.1a, в который добавлен TLSv1.2, был выпущен в апреле 2012 года. Таким образом, дистрибутивные версии Python, вероятно, будут иметь надежные шифры. Другое дело, что для каждой версии Python требуется определенная версия OpenSSL (например, Python 3.7 требует OpenSSL 1.0.2, я понимаю), но я не знаю точно, какие версии Python и что требуют.

В целом мне пришлось бы руководствоваться OWASP. Они говорят, что C- это «Наследие, самая широкая совместимость с настоящими старыми браузерами и устаревшими библиотеками» - с дополнительным бонусом в том, что на них можно ссылаться как на источник.

Кроме того, Python имеет свой собственный список шифров по умолчанию: он никогда не возвращается к значению по умолчанию OpenSSL (который, по-видимому, равен DEFAULT:!aNULL:!eNULL ). Он доступен как ssl._DEFAULT_CIPHERS хотя это внутреннее / недокументированное, поэтому способ доступа к значениям по умолчанию - никогда не вызывать set_ciphers () в SSLContext.

Для Python 3.6 _DEFAULT_CIPHERS равно

'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:DH+CHACHA20:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:DH+HIGH:RSA+AESGCM:RSA+AES:RSA+HIGH:!aNULL:!eNULL:!MD5:!3DES'

В Python 3.7 это

'DEFAULT:!aNULL:!eNULL:!MD5:!3DES:!DES:!RC4:!IDEA:!SEED:!aDSS:!SRP:!PSK'

с комментарием «ПО УМОЛЧАНИЮ: список шифров OpenSSL по умолчанию. Начиная с версии 1.0.2, список находится в разумном порядке».

Эти настройки кажутся довольно жесткими и в том же духе, что и OWASP.

Также есть _RESTRICTED_SERVER_CIPHERS который предназначен для использования на серверах (идеально подходит для стрельбы) и более жесткий, чем _DEFAULT_CIPHERS в некоторых версиях Python, но он является внутренним и нигде не используется - но был поддерживается по крайней мере с 3.4.

Таким образом, вариант 3 используется по умолчанию для набора шифров Python по умолчанию.

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги