سؤال

إليك مثال مثالي للمشكلة: جوهرة المصنف تكسر القضبان.

** السؤال الأصلي:**

الشيء الوحيد الذي يقلقني كمحترف أمني هو أن روبي ليس لديها ما يوازي خصوصية حزمة Java.وهذا يعني أن هذا غير صالح روبي:

public module Foo
  public module Bar
    # factory method for new Bar implementations
    def self.new(...)
      SimpleBarImplementation.new(...)
    end
    def baz
      raise NotImplementedError.new('Implementing Classes MUST redefine #baz')
    end
  end

  private class SimpleBarImplementation
    include Bar
    def baz
      ...
    end
  end
end

سيكون من الرائع حقًا أن تكون قادرًا على منع تصحيح القرود لـ Foo::BarImpl.وبهذه الطريقة، يعرف الأشخاص الذين يعتمدون على المكتبة أنه لم يعبث بها أحد.تخيل لو قام شخص ما بتغيير تطبيق MD5 أو SHA1 عليك!يمكنني الاتصال freeze في هذه الفئات، ولكن يجب أن أفعل ذلك على أساس كل فئة على حدة، وقد تقوم البرامج النصية الأخرى بتعديلها قبل أن أنتهي من تأمين طلبي إذا لم أكن كذلك جداً حذرا بشأن ترتيب التحميل.

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

(ولا، لا يتم تجميد الفئات الأساسية افتراضيًا في روبي.انظر أدناه:)

require 'md5'
# => true
MD5.frozen?
# => false
هل كانت مفيدة؟

المحلول

الدفع غير قابل للتغيير بواسطة غاري دولي.

يمكنك منع إعادة تعريف الأساليب الفردية.

نصائح أخرى

لا أعتقد أن هذا مصدر قلق.

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

أحد المخاوف النموذجية هو:أنا أكتب هذه المكتبة الرائعة، والتي من المفترض أن يتم استخدامها على النحو التالي:

require 'awesome'
# Do something awesome.

ولكن ماذا لو استخدمه شخص ما بهذه الطريقة:

require 'evil_cracker_lib_from_russian_pr0n_site'
# Overrides crypto functions and sends all data to mafia
require 'awesome'
# Now everything is insecure because awesome lib uses 
# cracker lib instead of builtin

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

للعودة إلى مثال Java الخاص بك:صحيح أنه في Java يمكنك إنشاء رمز التشفير الخاص بك private و final وما لا.ومع ذلك، يمكن لأي شخص ما زال استبدال تنفيذ التشفير الخاص بك!في الواقع، قام شخص ما بالفعل بما يلي:تستخدم العديد من تطبيقات Java مفتوحة المصدر OpenSSL لتنفيذ إجراءات التشفير الخاصة بها.وكما تعلم، فقد تم شحن دبيان مع نسخة معطلة وغير آمنة من OpenSSL لسنوات.لذا، فإن جميع برامج Java التي كانت تعمل على دبيان خلال العامين الماضيين في الواقع فعل تشغيل باستخدام تشفير غير آمن!

توفر Java الكثير من الأدوات الأخرى للبرمجة الدفاعية

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

ومع ذلك، يبدو أنك تتحدث بالفعل عن "الدفاع عن شفرتك من المبرمجين الآخرين".

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

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

على أي حال، إذا كانت مثل هذه الأشياء تثير قلقك كثيرًا، فإن روبي ليست لغة البرمجة المناسبة لك.إن Monkeypatching موجود هناك حسب التصميم، وعدم السماح به يتعارض مع الهدف الأساسي لهذه الميزة.

أعتقد أن روبي تتمتع بهذه الميزة - وهي ذات قيمة أكبر لأنها مشكلة أمنية.كتابة البطة أيضًا.
على سبيل المثاليمكنني إضافة أساليبي الخاصة إلى فئة Ruby String بدلاً من توسيعها أو تغليفها.

"قم بتثقيف زملائك في العمل، أو احصل على زملاء عمل أفضل" يعد أمرًا رائعًا بالنسبة للشركات الصغيرة الناشئة، كما أنه يعمل بشكل رائع مع الشركات الكبيرة مثل Google وAmazon.من السخف الاعتقاد بأن كل مطور متواضع قد تعاقد مع بعض تطبيقات المخططات الطبية الصغيرة في عيادة طبيب في مدينة صغيرة.

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

أنا لست قلقا بشأن هذا:

require 'evil_cracker_lib_from_russian_pr0n_site'
require 'awesome'

أنا قلق بشأن awesome تتطلب foobar و fazbot, ، و foobar تتطلب has_gumption, ، و ...في نهاية المطاف، يتعارض اثنان من هذه الأمور بطريقة غامضة تؤدي إلى إلغاء جانب أمني مهم.

أحد المبادئ الأمنية المهمة هو "الدفاع في العمق" - حيث تساعدك إضافة طبقات الأمان الإضافية هذه على تجنب إطلاق النار على قدمك عن طريق الخطأ.لا يمكنهم منع ذلك تمامًا؛لا شيء يمكن.لكنهم يساعدون.

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

غير قابل للتغيير

يمكنك إلقاء نظرة على لماذا مشروع "Sandbox" الخاص بـ Lucky Stiff، والذي يمكنك استخدامه إذا كنت قلقًا بشأن احتمال تشغيل تعليمات برمجية غير آمنة.http://code.whytheluckystiff.net/sandbox/

مثال (TicTacToe عبر الإنترنت):http://www.elctech.com/blog/safely-expose-your-app-to-a-ruby-sandbox

راجانوالد لديه المنشور الاخير حول هذا.وفي النهاية يبني ما يلي:

class Module
  def anonymous_module(&block)
   self.send :include, Module.new(&block)
  end
end

class Acronym
  anonymous_module do
    fu = lambda { 'fu' }
    bar = lambda { 'bar' }
    define_method :fubar do
      fu.call + bar.call
    end
  end
end

أن يفضح fubar كطريقة عامة على Acronymق، ولكن يحافظ على الشجاعة الداخلية (fu و bar) خاص ويخفي الوحدة المساعدة من العرض الخارجي.

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

إذا قاموا بتغيير طريقة ما، فيجب أن تبدأ في البحث عن سبب تغيير الطريقة.هل قاموا بتغييره بسبب بعض سلوكيات حالة الحافة أم أنهم قاموا بالفعل بإصلاح الخلل؟خاصة في الحالة الأخيرة، فإن Monkeypatch هو أمر إلهي، لأنه يصلح خطأً في العديد من الأماكن.

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

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