سؤال

إذا كنت أقوم بتقييم سلسلة بايثون باستخدام eval()، ولدي فئة مثل:

class Foo(object):
    a = 3
    def bar(self, x): return x + a

ما هي المخاطر الأمنية إذا كنت لا أثق في السلسلة؟بخاصة:

  1. يكون eval(string, {"f": Foo()}, {}) غير آمنة؟بمعنى، هل يمكنك الوصول إلى نظام التشغيل أو النظام أو أي شيء غير آمن من مثيل Foo؟
  2. يكون eval(string, {}, {}) غير آمنة؟بمعنى، هل يمكنني الوصول إلى نظام التشغيل أو النظام بالكامل من خلال مكونات مدمجة مثل len وlist؟
  3. هل هناك طريقة لجعل العناصر المدمجة غير موجودة على الإطلاق في سياق التقييم؟

هناك بعض السلاسل غير الآمنة مثل "[0] * 100000000" لا أهتم بها، لأنها في أسوأ الأحوال تؤدي إلى إبطاء/إيقاف البرنامج.أنا مهتم في المقام الأول بحماية بيانات المستخدم خارج البرنامج.

بوضوح، eval(string) بدون قواميس مخصصة غير آمن في معظم الحالات.

هل كانت مفيدة؟

المحلول

لا يمكنك تأمين التقييم باستخدام نهج القائمة السوداء مثل هذا.يرى إيفال أمر خطير حقا للحصول على أمثلة للمدخلات التي ستفصل مترجم CPython، وتمنح حق الوصول إلى أي فصل تريده، وما إلى ذلك.

نصائح أخرى

eval() سيسمح للبيانات الضارة باختراق نظامك بأكمله، وقتل قطتك، وأكل كلبك، وممارسة الحب مع زوجتك.

كان هناك مؤخرًا موضوع حول كيفية القيام بهذا النوع من الأشياء بأمان في قائمة python-dev، وكانت الاستنتاجات:

  • من الصعب حقًا القيام بذلك بشكل صحيح.
  • يتطلب تصحيحات لمترجم بايثون لمنع العديد من فئات الهجمات.
  • لا تفعل ذلك إلا إذا كنت تريد ذلك حقًا.

ابدأ هنا لتقرأ عن التحدي: http://tav.espians.com/a-challenge-to-break-python-security.html

ما الموقف الذي تريد استخدام eval() فيه؟هل تريد أن يتمكن المستخدم من تنفيذ تعبيرات عشوائية؟أم أنك ترغب في نقل البيانات بطريقة ما؟ربما يكون من الممكن قفل الإدخال بطريقة ما.

يمكنك الوصول الى os باستخدام وظائف مدمجة: __import__('os').

بالنسبة لبيثون 2.6+، فإن وحدة أست قد يساعد؛بخاصة ast.literal_eval, ، على الرغم من أن ذلك يعتمد على ما تريد تقييمه بالضبط.

لاحظ أنه حتى إذا قمت بتمرير قواميس فارغة إلى eval()، فلا يزال من الممكن فصل (C)Python ببعض الحيل النحوية.على سبيل المثال، جرب هذا مع مترجمك الفوري: eval("()"*8**5)

ربما يكون من الأفضل لك أن تقلب السؤال:

  1. ما نوع التعبيرات التي تريد تقييمها؟
  2. هل يمكنك التأكد من أن السلاسل التي تطابق بعض التركيبات المحددة بدقة هي فقط eval()d؟
  3. ثم فكر فيما إذا الذي - التي آمن.

على سبيل المثال، إذا كنت تريد السماح للمستخدم بإدخال تعبير جبري للتقييم، ففكر في قصره على أسماء متغيرات مكونة من حرف واحد وأرقام ومجموعة محددة من العوامل والوظائف.لا تقم بتقييم السلاسل () التي تحتوي على أي شيء آخر.

هناك جيدة جدا مقال عن عدم الأمان eval() في مارك بيلجريم الغوص في بايثون درس تعليمي.

مقتبس من هذا المقال:

في النهاية ، من الممكن تقييم تعبيرات الثعبان غير الموثوق بها بأمان ، من أجل بعض التعريفات "الآمنة" التي تبين أنها لا تكون مفيدة بشكل رهيب في الحياة الحقيقية.لا بأس إذا كنت تلعب فقط ، فلا بأس إذا قمت بتمرير مدخلات موثوق بها فقط.لكن أي شيء آخر يسأل فقط عن المتاعب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top