Kodokon kodokon.com

الأمن: حقن SQL، والامتيازات، والعبارات المُحضَّرة

أعِد إنتاج حقن SQL، وحيّده بالعبارات المُحضَّرة، وطبِّق مبدأ الامتياز الأدنى.

11 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يحدث حقن SQL لحظة سَلسَلة بيانات غير موثوقة داخل نص الاستعلام. فيقدّم المهاجم قيمة تُغلق السلسلة وتختطف المنطق. لنُعِد إنتاج الهجوم على جدول users: إن سَلسَلة المُدخَل ada' OR '1'='1 مباشرةً تحوّل مرشِّحًا دقيقًا إلى شرط دائم الصحة.

SQL
CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  is_admin INTEGER NOT NULL DEFAULT 0
);

INSERT INTO users (id, name, is_admin)
VALUES (1, 'ada', 0), (2, 'root', 1);

-- Dangerous concatenation (NEVER do this)
-- input = ada' OR '1'='1
SELECT * FROM users
WHERE name = 'ada' OR '1'='1';
الاستعلام المحقون يُرجِع كل الصفوف.

تنجح الحمولة لأن علامة الاقتباس تُغلق قبل الأوان القيمة الحرفية 'ada'، ثم يضيف OR '1'='1' شرطًا صحيحًا كليًّا. وتلحق صيغة أخرى -- لتعطيل بقية الاستعلام الأصلي كتعليق. والدرس المستفاد: ما دامت البيانات والكود يتشاركان السلسلة نفسها، فلا يكون أيّ إفلات يدوي موثوقًا حقًّا.

SQL
-- Positional placeholder
SELECT * FROM users WHERE name = ?;

-- Named placeholder
SELECT * FROM users WHERE name = :name;
شكلان من المعامِلات المربوطة في SQLite.

العلاج هو العبارة المُحضَّرة: يُصرِّف المُشغِّل (driver) أولًا بنية الاستعلام، ثم يربط القيم على حدة. ولا تُحلَّل البيانات المربوطة أبدًا كأنها SQL، بل تُقارَن فقط. وكميزة إضافية، فإن البنية المُصرَّفة قابلة لإعادة الاستخدام: فربط عدة قيم تباعًا يتجنّب إعادة تصريف الخطة عند كل استدعاء.

SQL
-- The bound value stays data, not SQL
SELECT * FROM users
WHERE name = :name;
-- :name = ada' OR '1'='1
-- -> 0 rows: no user
--    is literally named that
الحمولة نفسها، لكنها الآن غير ضارّة.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. لماذا تمنع العبارة المُحضَّرة ذات المعامِلات حقن SQL؟
    • لأنها تشفّر القيم المُرسَلة
    • لأن القيمة المربوطة تُعامَل كبيانات، ولا تُحلَّل أبدًا كأنها SQL
    • لأنها تُفلِت علامات الاقتباس في السلسلة تلقائيًّا
    • لأنها تحدّ من طول مُدخَل المستخدم
  2. تنجح الحمولة ' OR '1'='1 في الحقن لأنها...
    • تُشبِع ذاكرة خادم قاعدة البيانات
    • تُغلق القيمة النصّية الحرفية ثم تضيف شرطًا دائم الصحة
    • تُسقِط الجدول المستهدَف بالاستعلام
    • تغيّر امتيازات المستخدم الحالي
  3. هل يمكنك ربط اسم جدول عبر مُعامِل ?؟
    • نعم، تقبل العناصر النائبة أيّ نوع من المُعرِّفات
    • لا: تربط العناصر النائبة القيم فقط؛ ويجب التحقق من المُعرِّف مقابل قائمة سماح
    • نعم، لكن فقط بالصيغة المُسمّاة :name
    • نعم، شرط أن يكون الجدول موجودًا سلفًا