نصائح أمنية للمطوّرين – الجزء الأول

عندما كنت في المرحلة الجامعية درست العديد من لغات البرمجة، ولكن في تلك الفترة لم يكن هناك للحماية مكان. كتابة برنامج يقوم بأمر ما وبسرعة. لهذا لم تتطرق المواد في وقتها الى هجمات الفيض (Buffer Overflow)  او هجمات الحقن (SQL Injection) على سبيل المثال. وعندما تنتقل لسوق العمل سوف تستمر بذات العقلية ولكن بشكل أسوأ. فالشركات يهمّها طرح برامج أو تطبيقات تحتوي على العديد من الميّزات وبسرعة. عندها يقع المبرمج أوالمطوّر تحت ضغط الوقت فهو يريد الانتهاء من المشروع الذي يعمل عليه بأسرع وقت والحماية إن كانت في وارده لن تأخذ أولوية كونها (في اعتقاده) سوف تأخره عن تسليم المشروع.

الأمر الآخر لنفرض أنك مطوّر برنامج حاسوب وتريد أن تنتقل الى تطوير تطبيقات للويب. تقوم بالبحث عن كتاب يتحدّث عن البرمجة بلغة PHP مثلاً، وتبدأ القراءة واتباع الامثلة في الكتاب. الكتاب قد يكون مفيداً جدّاً وستقوم بتطبيق ما تعلمته من الكتاب في ببناء أول تطبيق لك موجّهٍ للويب. هذا أمر جميل. ولكن للاسف غالبيّة الكتب سوف تقوم بتعليمك عادات سيئة ستؤدي الى تطويرك لتطبيقات مليئة بالثغرات.

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

التحقق من المدخلات

اولى النصائح هي المتعلقة بالتّأكد من مدخلات المستخدم. يجب أن تضع في نصب عينك قاعدة تقوم على ان لا تثق بأي شيء يقوم المستخدم بإدخاله، أبداً. الغالبية الساحقة من الهجمات التي نسمع عنها سببها هو أن التطبيقات لم تقم بالتحقق من مدخلات المستخدم. فهجمات Cross-site Scripting او SQL Injection السبب الرئيسي في نجاحها هو ضعف التحقق أو غيابه تماماً.

كيف نقوم بالتحقق؟

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

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

هل هناك حروف خاصة مثل < أو > في اسم المستخدم؟ ماذا عن %00؟ أو “”؟ ماذا عن :؟ كما ترى هذه رموز تستخدم في هجمات مثل XSS أو الحقن أو البايت الفارغ، الخ. هناك العديد من هذه الرموز والتغييرات التي يمكن ان تشملها عن الترميز وخلافه. إذا لو أردنا وضع ذلك في قائمة ستكون لدينا قائمة طويلة من الممنوعات. ضع في اعتبارك انّك ستحتاج الى إضافة رموز بشكل مستمر الى هذه القائمة عندما يظهر هجوم جديد. هذه العملية ستستغرق منك وقتاً وجهداً ولهذا فإن طريقة القائمة السوداء هنا ليست بالطريقة المثلى للتحقق من مدخلات المستخدم.

طريقة القائمة البيضاء في هذه الحالة تعتبر أفضل بكثير. على فرض أن تطبيقك يقبل مدخلات باللغتين العربية والانجليزية. عندها سيكون لديك مجموعة الحروف العربية (أ-ي) ومجموعتان من الحرف الانجليزية (A-Z) و (a-z) ومجموعتا ارقام (للارقام العربية والارقام الهندية). قد تسمح لاسم المستخدم أن يحتوي على (-) أو (_). أي شيء سوى ذلك ستقوم بمنعه وانتهى.

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

أين تقوم بالتحقق؟

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

لهذا من الأفضل أن تقوم بعملية التحقق من مدخلات المستخدم على حاسوب المستخدم وعلى الخادم معاً.

التحكم بالرسائل الظاهرة للمستخدم

الرسائل التي تخرجها التطبيقات بشكل عام وتطبيق الويب بشكل خاص قد تعطي تفاصيل للمهاجمين تساعدهم في تنفيذ هجوم على الموقع. الرسائل مفيدة للمستخدم العادي في فهم ما يدور وتنبيهِه للخطأ الذي قام بارتكابه ولكن لا يجب أن يكون الرسالة تفصيلية.

لنأخذ المثال التالي:

مستخدم يريد تسجيل دخول الى موقع ما

رسالة تفصيلية حول الخطأ الذي قام المستخدم بارتكابه

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

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

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

معالجة رسائل الخطأ

الجانب الآخر من الرسائل هو ما تقوم به البرامج في قيام المستخدم بإدخال قيمة غير متوقعة. مثلاً


Microsoft runtime error
Type mismatch

هذه الرسالة مختصرة ولكنها تعطي معلومات عن التطبيق نفسه. بعض رسائل الخطأ تعطي تفاصيل أكبر للمهاجم مثل

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in /var/www/html/security4arabs/v1/lib/myniceapp.php on line 123

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

عودة للمثال الأول. لنفرض ان القيمة التي يتوقعها التطبيق هي قيمة رقمية.  المهاجم سوف يحاول تغذية التطبيق بقيمة لا يتوقعها من أجل دراسة رسالة الخطأ التي ستظهر. غالبية لغات الويب تدعم مكتبات تقوم بفحص القيمة المدخلة كل المطلوب فعله من قول المطوّر هو استخدامها. مثل الدالة is_numeric في PHP


if (is_numeric($product_id)) {
DO SOMETHING
} else {
echo "القيمة المدخلة غير مقبولة"
}

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

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

في الجزء الثاني إن شاء الله سنتناول الجلسات والكعكات 🙂 (cookies)

نبذة عن الكاتب

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

التعليقات:

أضف تعليقاً | عدد التعليقات: (7)

  1. pdz قال:

    مقالك جميل أخي العزيز ,
    ومن يتبع هذه التعليمات سوفى يتجنب أولا ثغرتي XSS/HTML Injection
    وثانيا يقلل من نسبة المعلومات التي سوفى يستنتجها اي شخص يحاول يستهدف موقعه أو السيرفر الذي عليه ومن بين تلك المعلومات مسارات الموقع واليوزر الخاص به واصدار php & mysql وغيرها
    وانا أتوقع الجزء الثاني راح يكون دسم ممم.
    ودمتم بود

  2. Hit-Man قال:

    السلام عليكم و رحمة الله و بركاته
    بارك الله فيكم أخي على هدا المقال الدي أنا أعتبره مهم لكل مبرمج لانه متل ما أقول هو يعطيك دينامية التفكير و الالية لفهم المنهج البرمجي
    أضن أنه المقال القادم سوف يكون اكتر احترافي لكن أتمنى أنه يتميز بشئ من المرونة التي أعتدناها في دروسكم
    بارك الله فيكم وشكرا لكم
    تحياتي

    • بشار قال:

      وعليكم السلام ورحمة الله وبركاته

      شكراً لك أخي الكريم. إن شاء الله يكون الجزء الثاني عند حسن توقع الجميع.

      إذا امكن ان توضح قليلاً المقصود بالمرونة؟

      شكراً لك

  3. Hit-Man قال:

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

  4. يونس قال:

    صراحة موضوع مهم بارك الله فيك
    المشكلة هي أن أغلب المبرمجين العرب متعجرفين ومغرورينولا يتقبلون النصحية ألا من رحمة ربك
    هذا الموضوع يذكرني بمحادثة مع صديقي مبرمج سألته ما الفرق بين Post و Get قال لي الـPost أكثر آمنة من الـGet لأنها لاتظهر في المتصفح وأنا أستعملها دائما ليكون موقعي آمن قلت له جيد وٱكملنا الحديث

أكتب تعليق