delphi4arab منتديات دلفي للعرب

نسخة كاملة : حقن قواعد البيانات SQL INJECTION
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
تحية طيبة وبعد 

حقن إس كيو إل ( SQL INJECTION)، أو حقن تعليمات الاستعلام البنيوية (SQL) , بهدف استغلال أي ثغرة أمنية موجودة بطبقة قاعدة البيانات التابعة لأي برنامج (DATABASE LAYER). هذه الثغرات ممكن أن تكون حاضرة عندما لا يتم تصفية مدخلات المستخدم لبعض الحروف والرموز الخاصة (ESCAPE CHARACTERS) المضمنة داخل جمل لغة الاستعلام البنيوية، أو ان لا يتم مراجعة نوعية المدخلات ان كانت نصية ام عددية (STRONGLY TYPED) مما يسبب عدم التكهن بنتيجة تنفيذها.

قمت بانشاء مثال بسيط عن حقن قواعد البيانات حيث البرنامج يقوم بتسجيل الدخول باسم وكلمة المرور كاجراء للتاكد من هوية المستخدم
فرضا اسم المستخدم في الجدول users

PHP كود :
1...admin.....admin
2.
..user.......pass 

لننظر الى جملة الاستعلام يجب ان يكون الاسم = edit1  و كلمة المرور = edit2 اي يجب تحقق الشرطين معا
وفي حالة عدم تصفية المدخلات يحدث التلاعب بالجمل المدخل لقواعد البيانات


PHP كود :
 try
    sltb 
:= SQLiteDatabase.GetTable('SELECT *  FROM `users` where username ="'+Edit1.text+'" AND password="'+Edit2.text+'"');

    if sltb.Count > 0 then
    Application
.MessageBox(PWideChar('Your account has been logged in - '+sltb.FieldAsString(sltb.FieldIndex['username'])),'info', MB_OK + MB_ICONINFORMATION)
    else
    Application.MessageBox('Username or Password is invalid', 'Error', MB_OK +MB_ICONSTOP);

 finally
 sltb
.Free;
 //
 end; 

لنعد للجملة 

PHP كود :
'SELECT *  FROM `users` where username ="'+Edit1.text+'" AND password="'+Edit2.text+'"' 

لو نقوم باستبدال edit2.text  بــــــــــــ 1" or ( "1"="1") and id=1;--

وبالتالي تصبح الجملة كالتالي  


PHP كود :
'SELECT *  FROM `users` where username ="'+Edit1.text+'" AND password="1" or ( "1"="1") and id=1;--"') 

اذا تم أستخدام الجملة السابقة بأجراء التأكد من هوية المستخدم (AUTHENTICATION PROCEDURE), فمن الممكن أستخدام هذه الطريقة للحصول على الصلاحية لأن نتيجة المعادلة '1'='1' هي دائما صحيحة (TRUE).
هذا حل مؤقت
PHP كود :
function Escape_String( const str: string): string;
var
  i: Byte;
const
  oldChars : array[0..8] of string[4]= ('\\',  '\x00', '\n',  '\r',  '''',  '"', '\x1a','--',';');
begin
  Result 
:= str;
  for i := 0 to high(oldChars) do
    Result := StringReplace(Result, oldChars[i], '', [rfReplaceAll])
end; 


PHP كود :
'SELECT *  FROM `users` where username ="'+Escape_String(Edit1.text)+'" AND password="'+Escape_String(Edit2.text)+'"' 
السلام عليكم
الحل استخدام البرامترات بدل من دمج السلاسل المحرفية
PHP كود :
'SELECT *  FROM `users` where username = :user AND password= :pass';
ParamByName('user').AsString := 'admin';
ParamByName('pass').AsString := 'admin';