Gunicorn: يعمل إعداد شفرات SSL الافتراضي على تعطيل أكثر الأصفار أمانًا

تم إنشاؤها على ٢٣ يناير ٢٠١٩  ·  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 ciphers إلى المجموعة ، عن طريق تغيير الافتراضي إلى السلسلة '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.

لبايثون 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'

مع تعليق يقول "DEFAULT: قائمة تشفير OpenSSL الافتراضية. منذ 1.0.2 القائمة في ترتيب معقول."

يبدو أن هذه الإعدادات ضيقة جدًا وبنفس روح OWASP.

هناك أيضًا _RESTRICTED_SERVER_CIPHERS وهو مخصص للاستخدام في الخوادم (مثالي جدًا لـ gunicorn) وهو أضيق من _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.

لبايثون 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'

مع تعليق يقول "DEFAULT: قائمة تشفير OpenSSL الافتراضية. منذ 1.0.2 القائمة في ترتيب معقول."

يبدو أن هذه الإعدادات ضيقة جدًا وبنفس روح OWASP.

هناك أيضًا _RESTRICTED_SERVER_CIPHERS وهو مخصص للاستخدام في الخوادم (مثالي جدًا لـ gunicorn) وهو أضيق من _DEFAULT_CIPHERS في بعض إصدارات Python ، لكن هذا داخلي ولا يُستخدم في أي مكان - ولكنه كان كذلك تم الاحتفاظ بها منذ 3.4.

لذا فإن الخيار 3 يكون افتراضيًا لمجموعة التشفير الافتراضية في Python.

السبب الوحيد لعدم القيام بذلك هو إذا كنا نعتقد أنه يمكننا شحن قائمة اليوم أكثر أمانًا من تلك الموجودة في إصدارات Python الأقدم ، أو أننا نريد الاشتراك في أحد مستويات OWASP الأكثر إحكامًا. بصراحة ، هذا هامشي جدًا.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات