انتقل إلى محتوى الدرس
الدرس 65
دورة MySQL

الحماية من حقن قواعد البيانات SQL Injection والاستعلامات المحضرة في MySQLMySQL SQL Injection Prevention and Prepared Statements

تعلّم الحماية من ثغرات حقن قواعد البيانات SQL Injection واستخدام الاستعلامات المحضرة (PREPARE و EXECUTE) في MySQL 8 مع أمثلة وتطبيقات تفاعلية.
أقسام الدرس
6
الأمثلة
5
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
7
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع
مخطط توضيحي لدرس الحماية من حقن قواعد البيانات SQL Injection والاستعلامات المحضرة في MySQL
مخطط توضيحي لدرس الحماية من حقن قواعد البيانات SQL Injection والاستعلامات المحضرة في MySQL

تُعد ثغرة حقن قواعد البيانات (SQL Injection — SQLi) من أخطر الثغرات الأمنية في هندسة البرمجيات على الإطلاق؛ وتنشأ عندما يقوم المبرمج ببناء جملة SQL عبر دمج نص المدخلات الواردة من المستخدم مباشرةً داخل نص الاستعلام بدلاً من فصل الكود عن البيانات:

  • الخلط الكارثي بين أوامر SQL وبيانات المستخدم: عندما يكتب التطبيق جملة نصية مدمجة مثل "SELECT * FROM users WHERE email = '" + input + "'"، فإن محلل خادم MySQL لا يستطيع التمييز بين الكود الذي كتبه المبرمج وبين النص الذي أدخله الزائر.
  • كسر علامات التنصيص: إذا أدخل المهاجم علامة تنصيص مفردة (') متبوعة بأوامر منطقية مثل OR أو UNION SELECT أو رمز التعليق (-- )، فإن نص المستخدم يخرج من كونه بيانات نصية ليتحول إلى أوامر SQL فعلية ينفذها الخادم!
  • المدخلات الرقمية معرضة للحقن أيضاً: حتى بدون علامات تنصيص، فإن دمج معرّف رقمي غير مفحوص مثل 105 OR 1=1 داخل WHERE id = ... يحقن شرطاً منطقياً كاملاً.
-- الاستعلام الطبيعي المقصود:
SELECT id, total_usd FROM orders WHERE order_code = 'ORD-500';

-- الاستعلام بعد تشويهه بدمج النصوص المباشر:
SELECT id, total_usd FROM orders WHERE order_code = '' OR 1=1;
SQL
-- Safe intended lookup for a single customer order:
SELECT id, customer_id, total_usd
FROM orders
WHERE order_code = 'ORD-500';

-- What happens when untrusted input "' OR '1'='1" is concatenated directly:
SELECT id, customer_id, total_usd
FROM orders
WHERE order_code = '' OR '1'='1';

لفهم آلية عمل الحماية الهندسية، دعنا نشرح بالتفصيل الدقيق كيف يحوّل النص الخبيث ' OR 1=1 -- شجرة التحليل النحوي (Syntax Tree) داخل محرك الاستعلام:

  • 1. الإغلاق المبكر للنص ('): تقوم علامة التنصيص الأولى التي يدخلها المهاجم بإغلاق علامة التنصيص التي فتحها المبرمج في WHERE email = '.
  • 2. زرع شرط صائب دائماً (OR 1=1): بما أن المعادلة 1=1 نتيجتها TRUE دائماً، يصبح شرط WHERE محققاً لكل صف في الجدول.
  • 3. تعطيل بقية الاستعلام بالتعليق (-- أو #): في MySQL، يحوّل الرمز -- (شرطتان متبوعتان بمسافة) أو الرمز # كل ما يأتي بعده في نفس السطر (مثل شرط التحقق من كلمة المرور أو حالة الحساب) إلى تعليق مهمل!
  • 4. تسريب جداول أخرى عبر UNION SELECT: إذا كان الموقع يعرض نتائج البحث، قد يحقن المهاجم UNION SELECT لدمج بيانات من جداول حساسة أخرى وعرضها على الشاشة.
SQL
-- Observe how Boolean logic evaluates inside the WHERE filter:
SELECT
  ('' = '' AND 'a' = 'b') AS normal_failed_login,
  ('' = '' OR 1 = 1)      AS injected_always_true;

-- Everything after '-- ' on the same line is ignored by the SQL parser:
SELECT 'admin_session_granted' AS status WHERE '' = '' OR 1 = 1 -- AND is_active = 0;

محاكي الوقاية من حقن SQL والاستعلامات المحضرة (Prepared Statements) في MySQL 8

تقضي الاستعلامات المحضرة مسبقاً (Prepared Statements / Parameterized Queries) على ثغرات حقن SQL نهائياً، لأنها تفصل فصلاً تاماً بين مرحلة بناء هيكل الاستعلام ومرحلة إرسال البيانات عبر مرحلتين مستقلتين في بروتوكول MySQL:

  • المرحلة الأولى — التحضير والترجمة (PREPARE): يرسل التطبيق نص الاستعلام مزوداً بعلامات استفهام (?) كمواضع حجز للقيم: SELECT id, email FROM users WHERE email = ?. يقوم خادم MySQL بتحليل الجملة نحوياً وبناء شجرة التنفيذ وتثبيتها نهائياً.
  • المرحلة الثانية — التنفيذ وتمرير القيم (EXECUTE): يرسل التطبيق قيم المتغيرات في حزمة مستقلة تماماً. وبما أن شجرة الاستعلام قد بُنيت واكتملت في المرحلة الأولى، يضع الخادم القيمة المرسلة داخل الخانة المخصصة لها كبيانات حرفية صمّاء، ولا يمررها على محلل أوامر SQL أبداً!
  • ميزة الأداء عند التكرار: عند تنفيذ نفس الاستعلام مئات المرات بقيم مختلفة، يوفر التحضير المسبق وقت التحليل النحوي المتكرر.
المرحلة 1 (PREPARE) : يبني الخادم هيكل الأمر -> SELECT id FROM users WHERE email = [PARAM_1]
المرحلة 2 (EXECUTE) : يضع القيمة كنص حرفي   -> [PARAM_1] = "' OR '1'='1" (استحالة تغيير الهيكل!)
SQL
PREPARE safe_lookup FROM
  'SELECT id, email, status FROM customers WHERE email = ? AND status = ?';

SET @email_param  = '[email protected]';
SET @status_param = 'active';

EXECUTE safe_lookup USING @email_param, @status_param;
DEALLOCATE PREPARE safe_lookup;

إلى جانب دوال التحضير في لغات البرمجة، يوفر خادم MySQL 8 أوامر SQL مباشرة للتحضير والتنفيذ وإخلاء الذاكرة، وتُستخدم بكثرة في الجلسات التفاعلية وداخل الإجراءات المخزنة الديناميكية:

  • PREPARE stmt_name FROM 'SELECT ... WHERE category = ? AND unit_price <= ?';: يترجم نص الاستعلام ويحفظه في ذاكرة الجلسة باسم stmt_name.
  • SET @cat = 'Storage', @max_p = 200.00;: يجهز القيم المراد تمريرها داخل متغيرات الجلسة المسبوقة بعلامة @.
  • EXECUTE stmt_name USING @cat, @max_p;: ينفذ الاستعلام المحضر ويربط المتغيرات بالترتيب مكان علامات الاستفهام (?).
  • DEALLOCATE PREPARE stmt_name; (أو المرادف DROP PREPARE stmt_name;): يحرر الذاكرة المحجوزة للاستعلام المحضر في الخادم فور انتهاء الحاجة إليه، مما يمنع استنزاف الحد الأقصى max_prepared_stmt_count.
+----+-------------------+-----------+------------+
| id | product_name      | category  | unit_price |
+----+-------------------+-----------+------------+
| 15 | NVMe SSD 2TB      | Storage   |     149.00 |
+----+-------------------+-----------+------------+
SQL
PREPARE filter_products FROM
  'SELECT id, product_name, category, unit_price
   FROM products
   WHERE category = ? AND unit_price <= ?
   ORDER BY unit_price ASC';

SET @cat_name  = 'Storage';
SET @max_price = 200.00;

EXECUTE filter_products USING @cat_name, @max_price;

DEALLOCATE PREPARE filter_products;

قاعدة هندسية بالغة الأهمية: علامات الاستفهام (?) في الاستعلامات المحضرة تقبل قيم البيانات فقط، ولا يمكن استخدامها لتمرير أسماء الجداول أو أسماء الأعمدة أو كلمات الترتيب مثل ASC / DESC! فكيف نسمح للمستخدم بترتيب النتائج حسب عمود يختاره بأمان تام؟

  • لماذا لا يعمل ORDER BY ? لترتيب الأعمدة؟ إذا مررت النص 'unit_price' مكان علامة الاستفهام في ORDER BY ?، فسيعامله MySQL كنص ثابت متساوٍ في كل الصفوف ولن يرتب الجدول!
  • الحل الأول — استخدام تعبير CASE الآمن داخل الاستعلام المحضر: مرر خيار المستخدم كقيمة عادية (?) داخل جملة CASE تحول الخيارات المسموحة فقط إلى الأعمدة الحقيقية المناظرة لها.
  • الحل الثاني — القائمة البيضاء الصارمة (Strict Whitelist): افحص اسم العمود المطلوب في كود التطبيق مقابل مصفوفة ثابتة من الأعمدة المسموحة فقط، وارفض أي قيمة خارج القائمة البيضاء فوراً.
+----+-------------------+------------+
| id | product_name      | unit_price |
+----+-------------------+------------+
| 10 | USB-C Hub         |      29.00 |
| 15 | NVMe SSD 2TB      |     149.00 |
+----+-------------------+------------+
SQL
PREPARE safe_sorted_products FROM
  'SELECT id, product_name, unit_price FROM products
   WHERE category = ?
   ORDER BY
     CASE WHEN ? = ''price_asc''  THEN unit_price END ASC,
     CASE WHEN ? = ''price_desc'' THEN unit_price END DESC,
     id ASC';
SET @cat = 'Storage', @sort = 'price_asc';
EXECUTE safe_sorted_products USING @cat, @sort, @sort;
DEALLOCATE PREPARE safe_sorted_products;

يلخص الجدول المرجعي التالي منظومة الدفاع المتكاملة متعددة الطبقات (Defense-in-Depth) لتأمين وإدارة قواعد بيانات MySQL 8 في بيئات الإنتاج:

طبقة الحماية الهندسيةالتطبيق القياسي في MySQL 8الخطر الأمني الذي تمنعه
1. الاستعلامات المحضرةPREPARE ... FROM '... WHERE col = ?' / PDOالقضاء الجذري على حقن قواعد البيانات (SQL Injection)
2. القائمة البيضاء للمعرفاتتعبير CASE أو التحقق الصارم من أسماء الأعمدةمنع الحقن في جمل الترتيب الديناميكية ORDER BY
3. تقييد الحسابات والمصادقةCREATE USER 'app'@'10.0.1.%' وتشفير SHA-256منع الاتصالات الخارجية غير المصرح بها وكسر كلمات المرور
4. مبدأ أقل الصلاحيات والأدوارGRANT SELECT, INSERT, UPDATE ON shop_db.*حصر صلاحيات التطبيق في قاعدته ومنع حذف الجداول
5. النمط الصارم والقيودSTRICT_TRANS_TABLES وقيود CHECK / FKرفض البيانات التالفة أو المقتطعة أو اليتيمة داخل المحرك
6. النسخ الاحتياطي والاستعادةmysqldump --single-transaction + السجل الثنائياستعادة البيانات بالكامل حتى أي ثانية تسبق الكارثة

ملخص الدرس: أتقنت في هذا الدرس كيف يؤدي دمج النصوص إلى ثغرات الحقن (SQLi)، وكيف تفصل الاستعلامات المحضرة (PREPARE / EXECUTE / DEALLOCATE PREPARE) الكود عن البيانات، وكيفية استخدام القائمة البيضاء لأسماء الأعمدة.
الخطوة التالية والدرس القادم: طبّق منظومة الحماية والأداء المتكاملة التي تعلمتها عبر دروس دورة MySQL 8.4 الخمسة والستين في مشاريعك الإنتاجية.

خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

إن الجمع بين الاستعلامات المحضرة (PREPARE / EXECUTE / DEALLOCATE PREPARE) والقائمة البيضاء لأسماء الأعمدة ومبدأ أقل الصلاحيات والنسخ الاحتياطي المتسق يتوّج إتقانك الهندسي الكامل لقواعد بيانات MySQL 8. الخطوة التالية: وظّف هذه المهارات الهندسية المتكاملة في بناء وتأمين قواعد بيانات تطبيقاتك الحقيقية!

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Prepared Statements الاستعلامات المحضرة
تعلّم الحماية من ثغرات حقن قواعد البيانات SQL Injection واستخدام الاستعلامات المحضرة (PREPARE و EXECUTE) في MySQL 8 مع أمثلة وتطبيقات تفاعلية.
للمراجعة
02 How String Concatenation Causes SQLi كيف يسبب دمج النصوص الحقن
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم كيف يسبب دمج النصوص الحقن في خادم MySQL 8.4.
للمراجعة
03 Anatomy of Authentication Bypass تشريح هجوم تجاوز الشرط
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم تشريح هجوم تجاوز الشرط في خادم MySQL 8.4.
للمراجعة
04 How Prepared Statements Separate Code فصل الكود عن البيانات المحضرة
المفهوم الهندسي الأساسي والصياغة التطبيقية لقسم فصل الكود عن البيانات المحضرة في خادم MySQL 8.4.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 SQLi SQLi
SQL Injection
ثغرة حقن قواعد البيانات الناتجة عن دمج مدخلات المستخدم النصية مباشرة داخل جملة SQL مما يغير منطق الاستعلام.
للمراجعة
02 AST AST
Abstract Syntax Tree
شجرة التحليل النحوي الداخلية للاستعلام التي يبنيها خادم MySQL ويثبتها خلال مرحلة التحضير PREPARE.
للمراجعة
03 PDO PDO
PHP Data Objects
واجهة الاتصال القياسية بقواعد البيانات في لغة PHP والتي تدعم الاستعلامات المحضرة وربط المعاملات الآمن.
للمراجعة
04 OWASP OWASP
Open Worldwide Application Security Project
المنظمة العالمية لأمن تطبيقات الويب التي تصدر المعايير القياسية للوقاية من ثغرات الحقن وحماية قواعد البيانات.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. نفّذ جمل SQL الواردة في قسم كيف يسبب دمج النصوص الحقن داخل بيئة MySQL 8 المحلية وتحقق من المخرجات.

  2. جرّب الحالات الثلاث داخل محاكي الوقاية من حقن SQL والاستعلامات المحضرة (Prepared Statements) في MySQL 8 في قسم تشريح هجوم تجاوز الشرط وقارن سلوك المحرك.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

6أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي6 أسئلة تنتظرك
01

ما السبب الجذري لحدوث ثغرة حقن قواعد البيانات (SQL Injection) في التطبيقات؟

دمج مدخلات المستخدم مباشرة داخل نص أمر SQL بدلاً من فصل الكود عن البيانات عبر الاستعلامات المحضرة.

02

لماذا يؤدي النص المحقون ' OR 1=1 -- إلى تجاوز شرط التحقق في استعلام مبني بدمج النصوص؟

يغلق علامة التنصيص مبكراً، ويضيف الشرط الدائم الصواب OR 1=1، ويحوّل بقية جملة WHERE إلى تعليق مهمل.

03

كيف تمنع الاستعلامات المحضرة (Prepared Statements) ثغرات حقن SQL عند تمرير مدخلات المستخدم؟

يبني الخادم شجرة الاستعلام ويثبتها بعلامات (?) في مرحلة PREPARE، ثم يعامل القيم الممررة في مرحلة EXECUTE كبيانات حرفية فقط ولا يترجمها كأوامر.

04

ما التسلسل الصحيح لأوامر SQL لتحضير استعلام بمعاملات وتنفيذه ثم تحرير ذاكرته في MySQL 8؟

التسلسل القياسي هو: PREPARE ثم EXECUTE ... USING ثم DEALLOCATE PREPARE.

05

لماذا لا يصلح وضع علامة الاستفهام (?) مباشرة مكان اسم العمود في ORDER BY ?، وما البديل الآمن؟

لأن (?) تربط القيم فقط فتُعامل كنص ثابت؛ والبديل الآمن هو استخدام تعبير CASE أو التحقق عبر قائمة بيضاء صارمة (Whitelist) لأسماء الأعمدة.

06

يؤدي تنفيذ الأمر DEALLOCATE PREPARE إلى تحرير الذاكرة المحجوزة للاستعلام المحضر داخل جلسة الخادم.

صواب؛ يحرر الأمر DEALLOCATE PREPARE موارد الذاكرة المرتبطة بالاستعلام المحضر في الجلسة.