SQL INJECTION
ويقصد بهذه النقطة إمكانية التأثير على سلوك النظام في نقاط معينة عن طريق تغيير سير تنفيذ الاستعلامات بعد إضافة شروط معينة تؤدي الى التلاعب بنتائج الاستعلام ويتحقق هذا السيناريو في معظم شاشات التقارير التي تقوم ببناء الاستعلام بناء على قيم حقول معينة ,وكذلك في الحقول التي تستخدم في البحث عن البيانات . وسوف يتم مناقشة ماتم التوصل الية من خلال البحث والتجربة في النقاط التالية
1- متغيرات في قاعدة البيانات تؤثر بشكل كبير على عمل النظام ومن أهمها
- FIXED_DATE والذي يعمل على تثبيت التاريخ عند قيمة معينة و بالتالي عند قراءة التاريخ عن طريق SYSDATE فإن النتيجة دائما ستكون القيمة المتروكة في المتغير هذا وبدون تغيير وبالتالي لابد من تفريغ محتوى هذا المتغير أثناء الدخول الى النظام
- متغيرات البيئة والثقافة NLS:ويقصد بها هنا تلك الإعدادات الخاصة بالأرقام والعملة والتاريخ والوقت وغير ذلك ,من الملاحظ أن معالج الاستعلامات في الأوراكل يعتمد على الكثير من متغيرات البيئة عند معالجة الاستعلامات أو مقارنة القيم أو عند التحويل من نوع بيانات الى نوع أخر وبالتالي لابد دوما وابد من التركيز على مبدأين اثنين وهما :
- التأكد من أن قيم متغيرات البيئة وفقا لما يجعل النظام يسلك السلوك الصحيح ولتحقيق هذه المبادئ لابد من يتم تعديل قيم هذه المتغيرات بالقيم الصحيحة على مستوى الجلسة session
- NLS_DATE_FORMAT
- NLS_NUMERIC_CHARACTERS
- NLS_CURRENCY
- إستخدام دوال التحويل بين أنواع البيانات عند المقارنة بين البيانات ولايتم المقارنة التلقائية لانه في هذه الحالة يتم الاعتماد على البيانات الموجودة في قيم متغيرات البيئة NLS
2- إرسال اسم الجدول أو العمود المراد الاستعلام منه في متغير الى استعلام يتم تنفيذه بشكل ديناميكي
- في بعض الحالات يكون اسم الجدول غير معروف حتى وقت تنفيذ العملية وبالتالي يضطر المطورون الى بناء جمل استعلام ديناميكية مما يؤدي الى أن الأسماء هذه عرضة للاختراق كأن
o يتم تضمين أكثر من اسم في نفس المتغير مثلا account, customer
o يتم الإشارة الى قاعدة بيانات خارجية عن طريق استخدام الرابط DB Linkبين قواعد البيانات
- في بعض الحالات يتم تغيير أسماء الأعمدة المراد الاستعلام عنها وقت التنفيذ وبالتالي يتم تظمين متغير خاص في الاستعلام ويتم تمريرة من المستخدم بأسماء الأعمدة المطلوبة وبالتالي قد يكون هذا النوع من الاستخدام عرضة للاختراق كأن يتم :
o تظمين إستعلام فرعي مثل a_code,(select sum(amt)from ias_post_dtl where a_code=a.a_code) amt
o تظمين أكثر من اسم عمود في نفس المتغير مثل A_code,A_name
- وبالتالي لابد من استخدام بعض الإجراءات للتعامل مع مثل هذه الحالات ليجعل عملية إساءة الاستخدام صعبة أو منعدمة
o يتم عادة تضمين أسماء الأعمدة أو الجداول التي يتم إرسالهم في متغيرات بين علامة التنصيص المزدوجة "name" وذلك لكي يتم تفسير كامل النص التي تم إرساله في المتغير الى كلمة واحدة.
o استخدام الدالة DBMS_ASSERT.SIMPLE_SQL_NAME لفحص قيمة المتغير التي تم إرسالها أنها مطابقة لمعايير التسميات في SQL مما يمنع استخدام الأحرف الخاصة مثل .,@ وهي الرموز التي يستطيع المستخدم من خلالها إساءة استخدام الكود
3- استخدام المتغيرات لبناء الاستعلامات الديناميكية
يتم استخدام المتغيرات لبناء الاستعلامات الديناميكية وقد تختلف قيمة المتغير باختلاف نوع البيانات وبالتالي بإمكان تقسيم استخدام المتغيرات بناء على نوع البيانات الى ثلاثة اقسام وهي البيانات النصية والرقمية والوقت/التاريخ .
- استخدام المتغيرات التي تحمل قيما نصية لبناء الاستعلامات الديناميكية وبالأخص في جزء where والتي يتم فيها تخصيص البيانات التي يتم إرجاعها للمستخدم , وإدخال قيم هذه المتغيرات مباشرة الى الاستعلامات تؤدي الى السماح للمستخدم بإساءة استغلال الكود عن طريق تضمين تعليمات معينة تؤدي الى انحراف مسار التنفيذ عن المسار المطلوب وبالتالي يجب تضمين الإجراءات التالية
o التأكد من أن النص التي تم إرساله لا يحتوي على علامة التنصيص المفردة ' .
o تضمين النصوص التي يتم مقارنتها بين علامتي تنصيص مفردة 'like this' .
o استخدام الدالة DBMS_ASSERT.ENQUOTE_LITERAL والتي تقوم بالتحقق من أن النص المرسل لا يحتوي على علامة تنصيص مفردة.
- استخدام المتغيرات التي تحمل وقت/تاريخ لبناء الاستعلامات الديناميكية وبالأخص في جزء where والتي يتم فيها تخصيص البيانات التي يتم ارجاعها للمستخدم , وإدخال قيم هذه المتغيرات مباشرة الى الاستعلامات تؤدي الى السماح للمستخدم بإساءة استغلال الكود عن طريق إساءة استغلال قيم المتغير العام nls_date_format وبالتالي لابد من اتخاذ الإجراءات التالية
o عادة عند المقارنة بين التواريخ يتم إستخدام الدالة TO_CHAR(DATE,FORMAT) حيث ان date يعبر عن القيم التي تم إرسالها من المستخدم بينما FORMAT تحتوي على التنسيق المطلوب للوقت والتاريخ او الدالة to_date(date,format) بحسب نوع المتغير الذي نريد الحصول علية او الدالة المستخدمة في الطرف الثاني من الاستعلام
o يتم تضمين المتغير الذي يحتوي على التاريخ في جملة الاستعلام الديناميكة بين علامتي تنصيص مفردة مثل where add_date>'''||:P_add_date||''' وذلك لجعل الموضوع اصعب على المخترق.
o لزيادة التأكيد يتم أيضا استخدام الدالة DBMS_ASSERT.ENQUOTE_LITERAL والتي تقوم بالتحقق من ان النص المرسل لايحتوي على علامة تنصيص مفردة. وذلك للناتج من الدالة to_char() او to_date()
- استخدام المتغيرات التي تحمل قيم رقمية لبناء الاستعلامات الديناميكية وبالأخص في جزء where والتي يتم فيها تخصيص البيانات التي يتم إرجاعها للمستخدم , وإدخال قيم هذه المتغيرات مباشرة الى الاستعلامات تؤدي الى السماح للمستخدم بإساءة استغلال الكود عن طريق إساءة استغلال قيم المتغير العام NLS_NUMERIC_CHARACTERS وبالتالي لابد من اتخاذ الإجراءات التالية
o تغيير قيمة المتغير العام الى القيم الافتراضية NLS_Numeric_Characters بداية كل جلسة والتي هي '.,'
o التعامل مع الدالة to_char(n,tm,nls) والتي تستقبل ثلاثة معاملات لتحويل الأرقام أثناء المقارنة بحيث أن n هو عبارة عن الرقم المراد تحويلة أو بالأصح القيمة التي تم استقبالها من المتغير TM هو عبارة عن التنسيق الموحد للأرقام التي طولها اقل من 64 و nls يتم تعبئة قيم المتغير NLS_NUMERIC_CHARACTERS='.,' بالقيم الافتراضية .
4- استخدام قائمة القيم المتعددة
استخدام قائمة القيم المتعددة : في جمل الاستعلام هناك إمكانية لمقارنة قائمة من القيم في الاستعلام عن طريق استخدام جملة IN(…) وبالتالي عندما تكون هذه القائمة في استعلام ديناميكي فقد نضطر الى أرسال قيمة هذه القائمة كسلسلة نصية في متغير ما وفي هذه الحالة قد يتم استغلال هذه القيمة وإرسال تعليمات بطريقة معينة تتلاعب بطريقة تنفيذ الاستعلام وبالتالي لابد من تفادي استخدام مثل هذا النوع من الاستعلام عن طريق ما يلي:
o التعامل مع type حيث يتم تعريف نوع بيانات عام في قاعدة البيانات على ان يحتوي على عمود واحد من نوع نصي ومن ثم
تحويل المتغيرات التي تحتوي على سلاسل نصية تعبر عن قائمة قيم الى متغير من نوع type المعرف مسبقا لهذا الغرض في قاعدة البيانات
تحويل الاستعلام بعد جملة in الى استعلام فرعي من المتغير الذي تم إرساله في الدالة عن طريق استخدام select val from table(type)
تعبئة القيم المرسلة من التطبيق الى قائمة مؤقته يتم تعريفها من النوع الذي تم تعريفة مسبقا في قاعدة البيانات.
o إذا كانت هذه القيم عائدة من استعلام أخر فيتم تضمين الاستعلام أو استخدام ميزة الجداول المؤقتة.
5- التنفيذ الديناميكي لكود PL/SQL أو ما يسمى anonyms block
التنفيذ الديناميكي لكود PL/SQL أو ما يسمى anonyms block : وفي هذه الحالة قد يستخدم المطورون قيم متغيرات يتم إرسالها من قبل المستخدم أثناء البناء الديناميكي وتعتبر هذه ثغرة كبيرة جدا بإمكان المستخدم التحكم فيها لتنفيذ أي امر يحلم بتنفيذه في قاعدة البيانات وذلك باستخدام الأمر execute immediate وسيكون باستطاعته التحكم الكامل بقاعدة البيانات وبالتالي لابد من الحذر الشديد عند استخدام هذا النوع من الكود.
التوصيات
- لابد من تدريب الفريق تدريبا كاملا على الأساليب المعتمدة في SQL injection واقلها تلك الأساليب والحيل المستخدمة حتى الآن.
- لابد من تنفيذ كل التوصيات التي يوصي بها المحترفون لتفادي حصول SQL injection والتي تم تلخيص اهم تلك التوصيات في هذا المقال
- محاولة التحوير التقني لتقليل الاعتماد على البناء الديناميكي لجمل الاستعلام لصالح كتابة الجمل الثابتة التي لا يتم تغييرها وقت التنفيذ.
- محاولة فحص قيم المتغيرات التي تكون فيها القيم المتوقعة محدودة
- إسناد قيم المتغيرات التي يتم إرسالها الى متغيرات محلية في الكود البرمجي وذلك للتأكد من نوع البيانات وطول النص المتوقع
- تثبيت الاستعلام الديناميكي في متغيرات ذات طول محدد بحيث يكون هامش التجاوز في طول الاستعلام محدود
- فصل الشروط التي تتحقق من الصلاحيات عن الشروط التي تحتوي على أجزاء ديناميكية كأن يتم مثلا تطبيق تقنية الاستعلامات المتداخلة ...بحيث نظمن دائما وأبداً انه وفي حال تجاوز شروط محددة في الاستعلام لا يتم تجاوز الصلاحيات
- الاستبدال التام لعلامة التنصيص المفردة التي يتم تخزينها في قاعدة البيانات ونحن نقترح هذه العلامة ‘.
- دراسة إمكانية الاعتماد على تلك التقارير التي يتم بنائها من REF_Cursor والتي بموجبها سيكون هناك طبقة وسيطة بين التطبيق ومحرك التقارير وهي طبقة pl\sql والتي تمكننا من إجراء الفحوصات اللازمة للتأكد من سلامة البيانات المرسلة
- إيجاد حل ملائم يمنع المستخدم من إرسال lexical parameter & في الواجهات عند استخدام البحث وذلك لان هذه الخاصية إذا لم يتم توقيفها فإنها تمثل أكبر اختراق أمني للبيانات المسموح للمستخدم باستعراضها.
- في شاشات التقارير يتم فحص وجود القيم في الجداول الرئيسية حين يتم تظمين حقول تدل على تلك القيم في الشاشات وكذلك منع إستدعاء إجراء الطابعة في حال وجود خطأ في البيانات المدخلة.
References
- How to write SQL injection proof PL/SQL -ORACLE WHITEPAPER | MAY 2017
- Preventing SQL and PL/SQL Injection Attacks -Arup Nanda -Longtime Oracle Technologist
تعليقات
إرسال تعليق