معهد ترايدنت

أول معهد عربي إلكتروني لدروس التجارة الالكترونية وممارستها ودعم المواقع والمنتديات العربية وتعليم التصميم والبرمجة والتطوير

درس حماية من حقن قواعد البيانات sql injection في php

بسم الله الرحمن الرحيم والصلاة والسلام على أشرف المرسلين سيدنا محمد الصادق الوعد الأمين المقدمة في هذا الدرس، سأعلمك كيفية منع حقن SQL عند كتابة أكواد PHP...

Unknown

.:: مراقب ركن تطوير المواقع ::.
طاقم الإدارة
إنضم
18 أغسطس 2022
مستوى التفاعل
8
بسم الله الرحمن الرحيم والصلاة والسلام على أشرف المرسلين سيدنا محمد الصادق الوعد الأمين

المقدمة​

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


SQL-Injection.jpg

ماهو حقن قواعد البيانات Sql injection ؟​

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

كيف تمنع SQL Injection في PHP​

لمنع حقن SQL في المشروع PHP الخاص بك الذي يستخدم قاعدة بيانات MySQL. يجب عليك اتباع الخطوات التالية لكتابة كود PHP واستعلامات MYSQL.​

  1. التحقق من صحة بيانات الإدخال وفلترتها
  2. كتابة كود الاستعلام (Prepared Statement)
  3. كتابة بارامترات الاستعلام المربوطة به (Bind Query Parameters)
  4. تنفيذ الاستعلام
يمكن تحقيق الخطوات المذكورة أعلاه باستخدام PDO و MySQLi.

مثال​

فيما يلي نماذج مختصرة لكل من الثغرات الأمنية ومنع إدخال SQL Injection. سترى النتيجة لكلا النموذجين.

مخطط قاعدة البيانات والبيانات​

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

SQL:
CREATE TABLE `users` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `first_name` text NOT NULL,
  `last_name` text NOT NULL,
  `username` text NOT NULL,
  `password` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
 

INSERT INTO `users` (`id`, `first_name`, `last_name`, `username`, `password`) VALUES
(1, 'Super', 'Administrator', 'super_admin', 'super_admin#123'),
(2, 'Admin 1', 'Administrator', 'admin1', 'admin1#123'),
(3, 'Admin 2', 'Administrator', 'admin2', 'admin2#123');

نموذج إداخل المعلومات​

فيما يلي نموذج تسجيل الدخول لجلب بيانات المستخدم والتحقق منها. سأستخدم نوع حقل كلمة المرور "TEXT" للتوضيح فقط لهذا الدرس.

HTML:
<fieldset class="border px-2 py-3 mb-3">
    <form action="" method="POST">
        <div class="mb-2">
            <label for="" class="control-label">Username</label>
            <input type="text" name="username" class="form-control" value="<?php echo (isset($_POST['username'])) ? $_POST['username'] :'' ?>">
        </div>
        <div class="mb-2">
            <label for="" class="control-label">Password</label>
            <input type="text" name="password" class="form-control" value="<?php echo (isset($_POST['password'])) ? $_POST['password'] :'' ?>">
        </div>
        <div class="mb-2">
            <button class="btn btn-primary btn-sm" name="login">Submit</button>
        </div>
    </form>
</fieldset>

بيانات الادخال​

إستخدم "أي شيء" أو "x" = "x" كاسم مستخدم وكلمة مرور للنموذج واطلع على نتيجة تنفيذ استعلامات PHP أدناه.

مثال لكود PHP يحتوي ثغرة SQL​

يعد كود PHP التالي مثالاً على قابلية التعرض لعملية حقن SQL. حيث لم يتم فلترة أي من المدخلات وحمايتها
PHP:
 <?php
    if($_SERVER['REQUEST_METHOD'] == 'POST'){
        $username = $_POST['username'];
        $password = $_POST['password'];
 
        $sql =  "SELECT * FROM `users` where `username` = '{$username}' and `password` = '{$password}' ";
        $query = $conn->query($sql);
        $results = $query->fetch_all(MYSQLI_ASSOC);
var_dump($results);
    }
    ?>

النتيجة​

لاحظ الصورة التالية حيث تم جلب جميع البيانات في الجدول users حيث قمنا بوضع x=x عند ادخال الاسم وكلمة السر
وبهذه الحالة الاستعلام سيقوم بالتاكد ان كان username = admin أو x = x وهي تساوي نفسها طبعا, فيتم استغلال الثغرة وجلب جميع البيانات داخل الجدول.
php_preventing_sql_injection-vulnerable.png

مثال لكود PHP يمنع ثغرة SQL​

كود PHP التالي هو مثال على استعلام PHP الذي يمنع حقن SQL Injections. استخدمنا في الكود أدناه ب(MySQLi Prepared statement) وفلترة بيانات الإدخال.
استخدما الدالة addslashes
شرح كامل عن الدالة من هنا

استخدمنا الدالة real_escape_string الخاصة بكلاس mysqli
شرح كامل عن الدالة من هنا

PHP:
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
    // فلترة المدخلات
    // addslashes تقوم باضافة علامة مائلة (\) قبل علامة الاقتباس الفردية والزوجية \" \'
    $username = addslashes($conn->real_escape_string($_POST['username']));
    $password = addslashes($conn->real_escape_string($_POST['password']));
 
    $sql2 =  "SELECT * FROM `users` where `username` = ? and `password` = ? ";
    // Prepare استخدام فنكشن
 
    $stmt = $conn->prepare($sql2);
 
    // binding query paramters "s = string"
    $stmt->bind_param('ss', $username, $password);
    $stmt->execute();
    $results = $stmt->get_result();
    $data = $results->fetch_all(MYSQLI_ASSOC);
    var_dump($data);
}
?>

النتيجة​

php_preventing_sql_injection-invulnerable.png

كما ترى تم فلترة المدخلات وتنقيتها من اخطار SQL Injections
قد تكون هذه الحماية غير كافية في بعض المواضع مثل ثغرة xss
فقد تحتاج فلترة المدخلات من اكود Html
مثلا دالة strip_tags حيث تقوم بازالة كافة اكود Html
او دالة htmlspecialchars وهذا شرح لها من هنا
او يمكنك برمجة دالة خاصة بك لتنظيف وفلترة المدخلات


بالتوفيق للجميع أي سؤال في مجال برمجة php,mysqli,Html,css أنا جاهز
 
التعديل الأخير:

traidant

.:: المدير العام ::.
طاقم الإدارة
إنضم
13 أغسطس 2022
مستوى التفاعل
17
العمر
34
الموقع الالكتروني
www.traidant.net
درس مفيد بارك الله فيك ..
ننتظر جديد دروسك الجميلة وسكربتاتك الاجمل .
بالتوفيق
 

Unknown

.:: مراقب ركن تطوير المواقع ::.
طاقم الإدارة
إنضم
18 أغسطس 2022
مستوى التفاعل
8
أعلى