سؤال

عند كتابة التعليمات البرمجية، هل تقوم ببرمجة دفاعية بوعي لضمان جودة عالية للبرنامج ولتجنب احتمال استغلال التعليمات البرمجية الخاصة بك بشكل ضار، على سبيل المثال.من خلال استغلال تجاوز سعة المخزن المؤقت أو حقن التعليمات البرمجية؟

ما هو مستوى الجودة "الحد الأدنى" الذي ستطبقه دائمًا على الكود الخاص بك؟

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

المحلول

في مجال عملي، يجب أن يكون الكود الخاص بنا عالي الجودة.
لذا فإننا نركز على أمرين أساسيين:

  1. اختبارات
  2. مراجعات الكود

هؤلاء يجلبون المال إلى المنزل.

نصائح أخرى

على غرار abyx، في الفريق الذي أعمل فيه، يستخدم المطورون دائمًا اختبار الوحدة ومراجعات التعليمات البرمجية.بالإضافة إلى ذلك، أهدف أيضًا إلى التأكد من عدم دمج التعليمات البرمجية التي يستخدمها الأشخاص يمكن الاستخدام - أميل إلى كتابة التعليمات البرمجية فقط للمجموعة الأساسية من الأساليب المطلوبة لكي يعمل الكائن الموجود في متناول اليد كما تم تحديده.لقد وجدت أن دمج الأساليب التي لا يجوز استخدامها أبدًا، ولكن توفير الوظائف يمكن أن يؤدي عن غير قصد إلى إدخال "باب خلفي" أو استخدام غير مقصود/غير متوقع في النظام.

من الأسهل العودة لاحقًا وتقديم الأساليب والسمات والخصائص التي يُطلب منها بدلاً من توقع شيء قد لا يأتي أبدًا.

أوصي بالدفاع عن البيانات التي تدخل "مكونًا" أو إطار عمل.ضمن "المكون" أو الإطار ينبغي للمرء أن يعتقد أن البيانات "صحيحة".

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

  1. تحقق دائمًا من البيانات من المصادر الخارجية والمستخدمين وما إلى ذلك
  2. يجب أن يتحقق "المكون" أو إطار العمل دائمًا من المكالمات الواردة.

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

قد تكون الصورة المرسلة من القمر الصناعي بمثابة حالة لمحاولة استرداد الأخطاء المتقدمة على...صورة تم تنزيلها من الإنترنت لوضع رمز خطأ ل...

أوصي الأشخاص بكتابة تعليمات برمجية تكون فاشية في بيئة التطوير وخيرية في الإنتاج.

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

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

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

inline const Vector3 Normalize( Vector3arg vec )
{
    const float len = Length(vec);
    ASSERTMSG(len > 0.0f "Invalid Normalization");
    return len == 0.0f ? vec : vec / len;
}

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

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

أشياء أخرى مثل تجزئة كلمات المرور، وتشفير سلاسل الاتصال، وما إلى ذلك.هي أيضا معيار.

من الآن فصاعدا، يعتمد الأمر على التطبيق الفعلي.

لحسن الحظ، إذا كنت تعمل مع أطر عمل مثل .Net، فإن الكثير من الحماية الأمنية تأتي مدمجة.

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

من المؤكد أن استخدام التطوير المبني على الاختبار يساعد.تكتب مكونًا واحدًا في كل مرة ثم تقوم بتعداد جميع الحالات المحتملة للمدخلات (من خلال الاختبارات) قبل كتابة الكود.وهذا يضمن أنك قمت بتغطية جميع القواعد ولم تكتب أيًا منها رائع رمز لن يستخدمه أحد ولكن قد ينكسر.

على الرغم من أنني لا أفعل أي شيء رسمي، إلا أنني عمومًا أقضي بعض الوقت في النظر إلى كل فصل والتأكد من ما يلي:

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

هذا يعتمد.

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

كلما زادت احتمالية استخدام الرمز، حتى في بعض الأحيان، أقوم بتكثيف مستوى عمليات التحقق.

  • الحد الأدنى من الأرقام السحرية
  • أسماء متغيرة أفضل
  • أطوال المصفوفة/السلسلة التي تم فحصها وتحديدها بالكامل
  • البرمجة من خلال تأكيدات العقد
  • اختبارات القيمة الخالية
  • الاستثناءات (اعتمادًا على سياق الكود)
  • التعليقات التوضيحية الأساسية
  • وثائق الاستخدام التي يمكن الوصول إليها (إذا كان بيرل وما إلى ذلك)

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

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

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

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

يجب ألا تتطلب الوظائف التي يتم استدعاؤها فقط من التعليمات البرمجية الخاصة بك التحقق من صحة المعلمات بشكل مفرط لأنك تتحكم في المتصل، أي أنه لا يتم تجاوز أي حدود خارجية.يجب أن تفترض الوظائف التي يتم استدعاؤها بواسطة رموز الآخرين أن المعلمات الواردة ستكون غير صالحة و/أو ضارة في مرحلة ما.

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

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

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

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

Java وJARs الموقعة وJAAS.

Java لمنع تجاوز سعة المخزن المؤقت واستغلال المؤشر/المكدس.

لا تستخدم JNI.(واجهة Java الأصلية) يعرضك لمكتبات DLL/المشتركة.

تم توقيع JAR لإيقاف تحميل الفصل باعتباره مشكلة أمنية.

يمكن لـ JAAS أن يسمح لتطبيقك بعدم الثقة بأي شخص، حتى بنفسه.

يحتوي J2EE على دعم مدمج (محدود) للأمان القائم على الدور.

هناك بعض النفقات العامة لبعض من هذا ولكن الثغرات الأمنية تختفي.

إجابة بسيطة: هذا يعتمد.الكثير من الترميز الدفاعي يستطيع يسبب مشاكل كبيرة في الأداء.

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