ربط المعلمة:ماذا يحدث تحت غطاء محرك السيارة؟

StackOverflow https://stackoverflow.com/questions/14934

  •  08-06-2019
  •  | 
  •  

سؤال

غالبًا ما توفر .NET وJava وغيرها من واجهات برمجة التطبيقات لقاعدة البيانات عالية المستوى بلغات مختلفة تقنيات تُعرف باسم البيانات المعدة وربط المعلمات بدلاً من إرسال أوامر نصية عادية إلى خادم قاعدة البيانات.ما أود معرفته هو ما يحدث عند تنفيذ عبارة مثل هذا:

SqlCommand cmd = new SqlCommand("GetMemberByID");
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("@ID", memberID);
para.DbType = DbType.Integer;
cmd.Parameters.Add(param);

أعلم أن هذه أفضل ممارسة.يتم تقليل هجمات حقن SQL بهذه الطريقة.ولكن ما الذي يحدث بالضبط تحت الغطاء عند تنفيذ هذه العبارات؟هل النتيجة النهائية لا تزال سلسلة SQL آمنة؟إذا لم يكن الأمر كذلك، ما هي النتيجة النهائية؟وهل هذا كافٍ لمنع هجمات حقن SQL؟

هل كانت مفيدة؟

المحلول

صفحة دليل MySQL في البيانات المعدة يوفر الكثير من المعلومات (والتي يجب أن تنطبق على أي نظام RDBMS آخر).

في الأساس، يتم تحليل بيانك ومعالجته مسبقًا، ويتم إرسال المعلمات بشكل منفصل بدلاً من معالجتها مع كود SQL.يؤدي هذا إلى التخلص من هجمات حقن SQL لأنه يتم تحليل SQL قبل تعيين المعلمات.

نصائح أخرى

في المصطلحات العادية:إذا تم إرسال بيان مُجهز، فستستخدم قاعدة البيانات خطة إذا كانت متوفرة، ولا يلزم إعادة إنشاء خطة في كل مرة يتم فيها إرسال هذا الاستعلام ولكن فقط قيم المعلمات هي التي تغيرت.هذا مشابه جدًا لكيفية عمل procs، والفائدة الإضافية مع procs هي أنه يمكنك منح الإذن من خلال procs فقط وليس للجداول الأساسية على الإطلاق

إذا كنت تستخدم MS SQL، فقم بتحميل ملف التعريف وسترى عبارات SQL التي يتم إنشاؤها عند استخدام الاستعلامات ذات المعلمات.فيما يلي مثال (أنا أستخدم Enterprise Libary 3.1، ولكن النتائج هي نفسها باستخدام SqlParameters مباشرة) مقابل SQL Server 2005:

string sql = "SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
  db.AddInParameter(cmd, "DomName", DbType.String, "xxxxx.net");
  db.AddInParameter(cmd, "Did", DbType.Int32, 500204);

  DataSet ds = db.ExecuteDataSet(cmd);
}

هذا يولد:

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did',
  N'@DomName nvarchar(9),
  @Did int',
  @DomName=N'xxxxx.net',
  @Did=500204

يمكنك أيضًا أن ترى هنا أنه إذا تم تمرير أحرف الاقتباس كمعلمات، فسيتم تجاوزها وفقًا لذلك:

db.AddInParameter(cmd, "DomName", DbType.String, "'xxxxx.net");

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did',
  N'@DomName nvarchar(10),
  @Did int',
  @DomName=N'''xxxxx.net',
  @Did=500204
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top