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

ماهو حقن قواعد البيانات Sql injection ؟
يتيح هجوم الحقن المعروف باسم (SQL Injection) تنفيذ أوامر SQL ضارة. تقوم هذه الأوامر بالتحكم بقاعدة بيانات الموقع او تطبيق الويب. تسمح عيوب حقن SQL للمهاجمين بالتغلب والالتفاف حول أمان التطبيق. والتحكم بالمحتوى الخاص لقاعدة بيانات SQL التابعة للموقع او تطبيق الويب, يمكنهم أيضًا إضافة السجلات وتغييرها وحذفها في قاعدة البيانات باستخدام حقن SQL.كيف تمنع SQL Injection في PHP
لمنع حقن SQL في المشروع PHP الخاص بك الذي يستخدم قاعدة بيانات MySQL. يجب عليك اتباع الخطوات التالية لكتابة كود PHP واستعلامات MYSQL.
- التحقق من صحة بيانات الإدخال وفلترتها
- كتابة كود الاستعلام (Prepared Statement)
- كتابة بارامترات الاستعلام المربوطة به (Bind Query Parameters)
- تنفيذ الاستعلام
مثال
فيما يلي نماذج مختصرة لكل من الثغرات الأمنية ومنع إدخال 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 يمنع ثغرة 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);
}
?>
النتيجة

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