SQL Injection — الجزء 1: الفهم — الأمن المتقدم
SQL Injection
ما هو SQL Injection؟
هجوم يحقن أوامر SQL ضارة عبر مدخلات المستخدم.
أنواع SQL Injection
Classic SQLi
' OR 1=1 --
Union-based
استخراج بيانات من جداول أخرى.
Blind SQLi
لا يظهر الخطأ، لكن يمكن استنتاجه.
Time-based
استخدام SLEEP() لاستنتاج المعلومات.
الوقاية
- ✅ Prepared Statements
- ✅ Parameterized Queries
- ✅ Input Validation
- ✅ Least Privilege
- ❌ String Concatenation
import sqlite3
import re
class SQLInjectionDemo:
"""
عرض توضيحي لـ SQL Injection وكيفية الوقاية
"""
def __init__(self):
# إنشاء قاعدة بيانات للاختبار
self.conn = sqlite3.connect(':memory:')
self.cursor = self.conn.cursor()
self._setup_db()
def _setup_db(self):
"""إعداد جداول الاختبار"""
self.cursor.execute('''
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username TEXT,
password TEXT,
email TEXT,
is_admin INTEGER
)
''')
# بيانات تجريبية
users = [
(1, 'admin', 'admin123', 'admin@example.com', 1),
(2, 'user1', 'pass123', 'user1@example.com', 0),
(3, 'user2', 'pass456', 'user2@example.com', 0),
]
self.cursor.executemany(
'INSERT INTO users VALUES (?, ?, ?, ?, ?)',
users
)
self.conn.commit()
# ❌ طريقة خاطئة - معرضة للـ SQLi
def vulnerable_login(self, username, password):
"""
⚠️ هذا كود ضعيف! للتوضيح فقط
"""
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
print(f"Query: {query}")
try:
self.cursor.execute(query)
result = self.cursor.fetchone()
return result
except Exception as e:
return f"Error: {e}"
# ✅ طريقة صحيحة - محمية
def secure_login(self, username, password):
"""
✅ استخدام Parameterized Queries
"""
query = "SELECT * FROM users WHERE username=? AND password=?"
print(f"Query: {query}")
print(f"Params: ({username}, {password})")
self.cursor.execute(query, (username, password))
return self.cursor.fetchone()
# التحقق من المدخلات
@staticmethod
def validate_input(user_input):
"""
فحص المدخلات للأنماط المشبوهة
"""
suspicious_patterns = [
r"('\s*OR\s*')",
r"(--)",
r"(;)",
r"(UNION\s+SELECT)",
r"(DROP\s+TABLE)",
r"(INSERT\s+INTO)",
r"(DELETE\s+FROM)",
]
for pattern in suspicious_patterns:
if re.search(pattern, user_input, re.IGNORECASE):
return False, f"نمط مشبوه: {pattern}"
return True, "OK"
# ===== عرض توضيحي =====
demo = SQLInjectionDemo()
print("=== محاولة تسجيل دخول عادية ===")
result = demo.vulnerable_login("admin", "admin123")
print(f"النتيجة: {result}\n")
print("=== هجوم SQL Injection ===")
# ' OR '1'='1 يجعل الشرط دائماً صحيح
malicious_input = "' OR '1'='1"
result = demo.vulnerable_login(malicious_input, malicious_input)
print(f"النتيجة: {result}")
print("⚠️ تم الدخول بدون كلمة مرور صحيحة!\n")
print("=== نفس الهجوم على الكود الآمن ===")
result = demo.secure_login(malicious_input, malicious_input)
print(f"النتيجة: {result}")
print("✅ الهجوم فشل!\n")
print("=== فحص المدخلات ===")
test_inputs = [
"normaluser",
"' OR 1=1 --",
"admin'; DROP TABLE users; --"
]
for test in test_inputs:
valid, msg = SQLInjectionDemo.validate_input(test)
status = "✅" if valid else "❌"
print(f"{status} '{test}' - {msg}")اختبر فهمك