English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

حقن SQL (Injection)

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

ما هو SQL Injection؟

SQL Injection هو هجوم يمكن للمهاجم من خلال إدخال بيانات (مثل إدخالات نموذج الويب) إلى خادم التطبيق عبر المتصفح تنفيذ أو إدخال كود SQL ضار.

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

كيف يعملSQL Injection

بالنظر إلى جملة SQL التالية، وهي مثال بسيط على التحقق من هوية المستخدم باستخدام اسم المستخدم وكلمة المرور في تطبيق الويب.

SELECT * FROM users WHERE username='username_val' AND password='password_val';

في هذا السياق،username_valوpassword_valوهذا يعني اسم المستخدم وكلمة المرور المدخلة من قبل المستخدم. إذا أدخل المستخدم مثلًا اسم مستخدم 'john' وكلمة مرور '123'، فإن الجملة الناتجة ستكون:

SELECT * FROM users WHERE username='john' AND password='123';

لكن لنفترض، إذا كان المستخدم هو المهاجم، لم يكن لديه أدخل اسم مستخدم وكلمة مرور صالحة في حقل الإدخال، بل أدخل قيمًا مشابهة للآتي: ' OR 'x'='x

في هذه الحالة، سيتم بناء استعلام SQL المذكور أعلاه كالتالي:

SELECT * FROM users WHERE username='' OR 'x'='x' AND password='' OR 'x'='x';

هذه الجملة هي جملة SQL صالحة، حيث أن WHERE 'x'='x' دائمًا يعود إلى true، لذا ستعود الاستعلام إلىusersكل سطر في الجدول. يمكنك رؤية أن المهاجم يمكنه الوصول بسهولة إلى جميع المعلومات الحساسة في قاعدة البيانات باستخدام حيلة صغيرة.

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

تحذير:إذا كان جهدك يولدDELETEأوUPDATEإذا قمت بالاستعلام، فإن تجاهل آثار ثغرة اختراق SQL يمكن أن يكون أسوأ. يمكن للهacker حذف بيانات من الجدول أو تعديل جميع الصفوف بشكل دائم.

منع اختراق SQL

تحقق دائمًا من إدخال المستخدم، لا تقم بأي افتراضات. لا تقم ببناء جملة SQL مباشرة من الإدخال. إذا كنت تستخدم PHP وMySQL، يمكنك استخدام دالة mysqli_real_escape_string() لإنشاء نصوص SQL صالحة يمكن استخدامها في جملة SQL.

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

<?php
// بدء الجلسة
session_start();
 
/* محاولة اتصال بخادم MySQL. */
   /* افترض أن تشغل خادم MySQL بشكل افتراضي (لا يحتوي المستخدم 'root' على كلمة المرور) */
$link = mysqli_connect("localhost", "root", "", "demo");
 
// التحقق من الاتصال
if($link === false){
    die("خطأ: لا يمكن الاتصال بالقاعدة البيانات.");
}
 
// تحويل إدخال المستخدم لضمان الأمان
$username_val = mysqli_real_escape_string($link, $_POST['username']);
$password_val = mysqli_real_escape_string($link, $_POST['password']);
 
if(isset($username_val, $password_val)){
    // محاولة تنفيذ الاستعلام
    $sql = "SELECT * FROM users WHERE username='" . $username_val . "' AND password='" . $password_val . "'";
    if($result = mysqli_query($link, $sql)){
        if(mysqli_num_rows($result) == 1){
            // المستخدم تم التحقق من هويتة، يرجى تنفيذ العمليات هنا
            $row = mysqli_fetch_array($result);
            /* حفظ القيم في متغيرات الجلسة، */
               لإمكانية الوصول إليها لاحقاً في نفس استدعاء الجلسة
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['first_name'] = $row['first_name'];
            header('Location: welcome.html');
        }
            echo "خطأ! اسم مستخدم أو كلمة المرور غير صحيحة.";
        }
    }
        echo "خطأ: حدث خطأ. حاول مجدداً.";
    }
}
 
// إغلاق الاتصال إغلاق الاتصال
mysqli_close($link);
?>

إشارة:إشارة: قم بفحص حجم وتنسيق أو محتوى البيانات المُستقبلة من التطبيق الاختباري، وألّف القيود المناسبة لمنع استغلال موارد النظام.