ما هو حقن SQL وكيفية منعه في تطبيقات PHP؟

هل تعتقد أن قاعدة بيانات SQL الخاصة بك فعالة وآمنة من التدمير الفوري؟ حسنًا ، لا يوافق SQL Injection!


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

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

ما هو حقن SQL?

مفتاح فهم SQL Injection في اسمه: SQL + Injection. لا تحتوي كلمة “حقن” هنا على أي دلالات طبية ، بل هي استخدام فعل “حقن”. معًا ، تنقل هاتان الكلمتان فكرة وضع SQL في تطبيق ويب.

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

لنفترض أنك تقوم بإنشاء موقع ويب PHP نموذجي لمتجر محلي للتجارة الإلكترونية ، لذلك قررت إضافة نموذج اتصال مثل هذا:

اسمك

رسالتك

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

<?بي أتش بي

$ name = $ _POST [‘name’] ؛
$ message = $ _POST [‘message’] ؛

// تحقق مما إذا كان لدى هذا المستخدم رسالة بالفعل
mysqli_query ($ conn, "SELECT * من الرسائل حيث name = $ name") ؛

// كود آخر هنا

لذلك تحاول أولاً معرفة ما إذا كان لدى هذا المستخدم بالفعل رسالة غير مقروءة. الاستعلام SELECT * من الرسائل حيث يبدو name = $ name بسيطًا بما فيه الكفاية ، أليس كذلك?

خطأ!

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

  • يعمل التطبيق على قاعدة بيانات SQL (اليوم ، كل تطبيق تقريبًا)
  • اتصال قاعدة البيانات الحالية لديه أذونات “تحرير” و “حذف” في قاعدة البيانات
  • يمكن تخمين أسماء الجداول الهامة

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

جو ؛ أوامر اقتطاع ؛؟ نعم سيدي! دعنا نرى ما سيصبح الاستعلام عندما يتم تنفيذه بواسطة برنامج PHP النصي:

حدد * من الرسائل حيث name = Joe؛ أوامر اقتطاع

حسنًا ، يحتوي الجزء الأول من الاستعلام على خطأ في بناء الجملة (لا توجد علامات اقتباس حول “Joe”) ، لكن الفاصلة المنقوطة تجبر محرك MySQL على بدء تفسير واحد جديد: أوامر اقتطاع. تمامًا ، في ضربة واحدة ، يختفي سجل الطلبات بالكامل!

الآن بعد أن تعرفت على كيفية عمل SQL Injection ، حان الوقت للنظر في كيفية إيقافه. الشرطين الذين يجب استيفاؤهما من أجل إدخال SQL بنجاح هما:

  1. يجب أن يحتوي برنامج PHP النصي على امتيازات تعديل / حذف في قاعدة البيانات. أعتقد أن هذا ينطبق على جميع التطبيقات ولن تتمكن من جعل تطبيقاتك للقراءة فقط. �� وخمن ماذا ، حتى لو أزلنا جميع امتيازات التعديل ، يمكن أن يسمح إدخال SQL لشخص ما بتشغيل استعلامات SELECT وعرض جميع قاعدة البيانات ، بما في ذلك البيانات الحساسة. بمعنى آخر ، لا يعمل تقليل مستوى الوصول إلى قاعدة البيانات ، ويحتاج تطبيقك إلى ذلك على أي حال.
  2. تتم معالجة إدخال المستخدم. الطريقة الوحيدة التي يمكن أن يعمل بها إدخال SQL هي عندما تقبل البيانات من المستخدمين. مرة أخرى ، ليس من العملي إيقاف جميع المدخلات لتطبيقك لمجرد أنك قلق بشأن إدخال SQL.

منع حقن SQL في PHP

الآن ، بالنظر إلى أن اتصالات قاعدة البيانات والاستعلامات ومدخلات المستخدم هي جزء من الحياة ، كيف نمنع إدخال SQL؟ لحسن الحظ ، الأمر بسيط جدًا ، وهناك طريقتان للقيام بذلك: 1) تطهير إدخال المستخدم ، و 2) استخدام البيانات المعدة.

تعقيم إدخال المستخدم

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

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

هناك عيب واحد في هذا النهج: إنها تقنية قديمة حقًا تتوافق مع الأشكال القديمة للوصول إلى قاعدة البيانات في PHP. اعتبارًا من PHP 7 ، لم تعد هذه الوظيفة موجودة ، مما ينقلنا إلى حلنا التالي.

استخدم العبارات المعدة

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

<?بي أتش بي
$ servername = "مضيف محلي"؛
اسم المستخدم $ = "اسم المستخدم"؛
$ password = "كلمه السر"؛
$ dbname = "myDB"؛

// إنشاء اتصال
$ conn = new mysqli ($ servername، $ username، $ password، $ dbname)؛

// تحقق من اتصال
إذا ($ conn->connect_error) {
موت("فشل الاتصال: " . conn $->connect_error) ؛
}}

// التحضير والربط
$ stmt = $ conn->إعداد("INSERT INTO MyGuests (الاسم الأول ، اسم العائلة ، البريد الإلكتروني) VALUES (؟،؟،؟)") ؛
$ stmt->bind_param ("sss", $ firstname ، $ lastname ، $ email) ؛

// تعيين المعلمات وتنفيذها
$ firstname = "يوحنا"؛
$ lastname = "ظبية"؛
$ email = "[البريد الإلكتروني محمي]
$ stmt->نفذ – اعدم()؛

$ firstname = "مريم"؛
$ lastname = "مو"؛
$ email = "[البريد الإلكتروني محمي]
$ stmt->نفذ – اعدم()؛

$ firstname = "جولي"؛
$ lastname = "دولي"؛
$ email = "[البريد الإلكتروني محمي]
$ stmt->نفذ – اعدم()؛

صدى صوت "تم إنشاء سجلات جديدة بنجاح"؛

$ stmt->أغلق()؛
conn $->أغلق()؛
?>

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

بالنسبة لأولئك الذين هم على دراية بالفعل بامتداد PDO لـ PHP ويستخدمونه لإنشاء عبارات جاهزة ، لدي نصيحة صغيرة.

تحذير: كن حذرًا عند إعداد شركة تنمية نفط عمان

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

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES ، صحيح) ؛

ما يفعله هذا الإعداد هو إخبار شركة تنمية نفط عمان بمحاكاة البيانات المعدة بدلاً من استخدام ميزة العبارات المعدة في قاعدة البيانات. وبالتالي ، يرسل PHP سلاسل استعلام بسيطة إلى قاعدة البيانات حتى لو كان رمزك يبدو أنه يقوم بإنشاء عبارات معدة وإعداد معلمات وكل ذلك. بمعنى آخر ، أنت عرضة لحقن SQL كما كان من قبل. ��

الحل بسيط: تأكد من تعيين هذا المضاهاة على خطأ.

$ dbConnection->setAttribute (PDO :: ATTR_EMULATE_PREPARES، false) ،

يضطر البرنامج النصي PHP الآن إلى استخدام عبارات معدة على مستوى قاعدة البيانات ، مما يمنع جميع أنواع إدخال SQL.

منع استخدام WAF

هل تعلم أنه يمكنك أيضًا حماية تطبيقات الويب من إدخال SQL باستخدام WAF (جدار حماية تطبيق الويب)?

حسنًا ، ليس فقط إدخال SQL ولكن العديد من الثغرات الأخرى من الطبقة 7 مثل البرمجة عبر المواقع ، والمصادقة المعطلة ، والتزوير عبر المواقع ، وتعريض البيانات ، وما إلى ذلك ، إما يمكنك استخدام الاستضافة الذاتية مثل Mod Security أو المستندة إلى السحابة على النحو التالي.

حقن SQL وأطر PHP الحديثة

يعد حقن SQL أمرًا شائعًا للغاية وسهلًا ومحبطًا وخطيرًا جدًا بحيث تأتي جميع أطر الويب PHP الحديثة مدمجة مع الإجراءات المضادة. في WordPress ، على سبيل المثال ، لدينا $ wpdb->تحضير الوظيفة () ، بينما إذا كنت تستخدم إطار عمل MVC ، فإنه يقوم بكل الأعمال القذرة من أجلك ولا داعي للتفكير في منع إدخال SQL. من المزعج بعض الشيء أنه في WordPress يجب عليك إعداد البيانات بشكل صريح ، ولكن مهلاً ، نحن نتحدث عن WordPress. ��

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

استنتاج

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

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map