SQL Injection
SQL Injection
SQL Injection
SQL injection يحدث عندما تدمج مدخلات المستخدم داخل نص SQL مباشرة. إذا كتب المستخدم قيمة تحتوي اقتباساً أو جزءاً من SQL، قد يتغير معنى الاستعلام. الحل الأساسي: استخدم parameters في لغة التطبيق، لا string concatenation.
بدلاً من بناء "... WHERE email = '" + email + "'", اكتب استعلاماً فيه placeholder مثل WHERE email = ? ومرر القيمة للdriver. هكذا تبقى القيمة قيمة، لا جزءاً من اللغة.
النمط الخطير — String Concatenation
# تحذير: لا تفعل هذا أبداً
user_input = "' OR '1'='1"
query = "SELECT * FROM users WHERE email = '" + user_input + "'"
# النتيجة: SELECT * FROM users WHERE email = '' OR '1'='1'
# → يُرجع كل المستخدمين
المهاجم يكتب ' OR '1'='1 كقيمة البريد الإلكتروني. حين تُدمج في نص SQL، يتغير معنى الاستعلام كلياً ويتحول الشرط إلى OR '1'='1' — وهو صحيح دائماً فيُرجع كل الصفوف.
حمولات شائعة:
| الحمولة | التأثير |
|---|---|
' OR '1'='1 | يُرجع كل الصفوف |
'; DROP TABLE users; -- | يحذف جدولاً كاملاً |
' UNION SELECT password, NULL FROM admins -- | يسرب بيانات جدول آخر |
النمط الآمن — Parameterized Queries
# Python — sqlite3
cursor.execute("SELECT * FROM users WHERE email = ?", (user_email,))
# Go — database/sql
db.Query("SELECT * FROM users WHERE email = ?", userEmail)
# Node.js — better-sqlite3
db.prepare("SELECT * FROM users WHERE email = ?").get(userEmail)
المبدأ واحد في كل اللغات: ? أو placeholder مشابه — القيمة تُمرَّر بشكل منفصل عن نص SQL. driver قاعدة البيانات يضمن أن القيمة لا تُفسَّر أبداً كـSQL.
لا تعتمد على التنظيف اليدوي
محاولة الهروب اليدوي من الاقتباسات ليست سياسة أمان كافية. استخدم API مخصصاً للمعاملات.