SQL Injection یکی از خطرناک ترین و رایج ترین آسیب پذیری های امنیتی است. اکثر برنامه ها به شدت به پایگاه های داده ای که هدف مستقیم این حمله اند، وابسته هستند. با تزریق SQL مخرب، مهاجم می تواند داده های شما را بدزدد یا تغییر دهد، جداول را نابود کند و کار های خرابکارانه مشابهی انجام دهد. این حمله می تواند با کوئری های SQL پویا که از یک ورودی کاربر نامعتبر وارد می شوند اتفاق بیفتد. در اینجا مثالی از نحوه کار آن می آوریم.
ما یک کوئری SQL ایجاد کرده ایم تا فهرست دانش آموزان را با نام خانوادگی دریافت کنیم. کاربر نهایی نامی را برای جستجو در یک فیلد متن وارد می کند. سپس آن مقدار وارد شده به یک سری از رشته های متنی الحاق شده و بر روی پایگاه داده اجرا می شود.
Select * FROM STUDENTS WHERE LASTNAME = "'" + LastName + "'";
شخص مهاجم به جای تایپ نام خانوادگی، SQL مخرب را وارد می کند.
Select * FROM STUDENTS WHERE LASTNAME = 'smith' OR '1'='1'--';
از یک کاراکتر ' برای بستن نام استفاده شده و عبارت یک برابر یک همراه با عبارت OR استفاده شده است که همیشه نتیجه آن برابر با مقدار true است و خط تیره های انتهایی بقیه کوئری را به کامنت تبدیل می کند.با این SQL که به برنامه تزریق شده، کوئری تمام دانش آموزان را انتخاب کرده و آنها را در خروجی کوئری در اختیار مهاجم قرار می دهد.
ما میتوانیم از این جلوتر رفته و احکام SQL به مراتب خطرناک تری را وارد کنیم.
افزودن یک کاراکتر ; ، کوئری مربوط به SELECT را به پایان میرساند و در ادامه آن یک کوئری حذف یک جدول قرار می دهیم. با این کار کل جدول دانش آموز حذف می شود.
Select * FROM STUDENTS WHERE LASTNAME = 'smith'; DROP TABLE Students;
این کار به شما نشان می دهد که این حملات چه نوع آسیبی را می تواند به سیستم وارد کند. با برخی از تکنیک هایی که در ادامه مرور خواهیم کرد، می توان از تزریق SQL ناخواسته جلوگیری کرد.
یکی این است که از نوشتن کوئری های SQL پویا که ورودی کاربر به آن اضافه می شود اجتناب کنیم.
استفاده از یک ORM(object relational mapper) مانند Entity Framework برای دسترسی به داده ها و دیتابیس، گزینه ایمنتری است.
اما اگر از stored procedure های ذخیره شده استفاده می کنیم، و اگر SQL داخل آنها به صورت پویا تولید می شود، ممکن است برنامه ما در معرض خطر قرار گیرد. در این صورت باید حتما از پارامترها استفاده کنیم.
استفاد از پارامتر ها، مزیت تعریف انواع داده ها را به ما می دهد و نیز امکان می دهد که به جای مقادیری که می خواهیم در کوئری استفاه کنیم از متغیر برای این منظور استفاده کنیم.
در اینجا نمونه ای از گرفتن فهرست دانش آموزان بر اساس نام خانوادگی نشان می دهیم، این بار با استفاده از یک stored procedure که ورودی آن یک پارامتر است. نام خانوادگی به عنوان یک پارامتر ارسال می شود و در پرس و جو گنجانده می شود. این نحوه استفاده از تزریق دستورات SQL جلوگیری می کند.
همین امر در مورد کوئری های پویا که در کد خود می نویسیم نیز صدق می کند.
PROCEDURE GetStudentByLastName(@LastName varchar(2)) AS BEGIN
SELECT FirstName, LastName From Students Where LastName = @LastName
به عنوان مثال، با استفاده از ado.net، از کوئری های پارامتری برای مقادیر پویا به جای ساخت خود رشته های کوئری استفاده کنید.
string sql = "SELECT * FROM students WHERE StudentId = @StudentId";
SqlCommand command = new SqlCommand(sql);
command.Parameters.Add(new SqlParameter("@StudenrtId", System.Data.SqldbType.Int));
command.Parameters["@StudentId"].Value = 1;
این مثال به شما نشان می دهد که چگونه دانش آموزان را با شناسه آنها جستجو کنید. و توجه کنید که ID یک پارامتر در کوئری است.
سپس می توانید از آبجکت SQL command در ado.net استفاده کنید. با تعریف پارامترها و اضافه کردن آنها به command ، می توانید کوئری خود را با خیال راحت در مقابل پایگاه داده اجرا کنید.
به عنوان آخرین راه حل، اگر استفاده از پارامترها جزو گزینه های مورد استفاده ما نیستند، می توانید تمام ورودی های کاربر را قبل از قرار دادن آن در یک کوئری ، از کد های مخرب پاکسازی کنید. این پاک سازی شامل اعتبارسنجی داده های ورودی و اعمال تغییرات رو کاراکترهای خاص مانند single quote (‘) است. یکی دیگر از اقدامات امنیتی مهمی که باید دنبال کنید استفاده از کاربر پایگاه داده ای با حداقل دسترسی به دیتابیس، برای برنامه خودتان است. به عنوان مثال این شناسه کاربری نباید برای انجام کارهایی مانند ایجاد و حذف کردن جداول یا تغییر سطوح دسترسی، مجوز داشته باشد. تمامی این مجوزها باید برای ادمین اصلی پایگاه داده محفوظ باشد. به پایگاه داده فقط باید مجوزهای لازم برای اجرای برنامه داده شود و نه بیشتر. این تمهیدات آسیبی را که حمله SQL Injection می تواند به سیستم شما وارد کند به حداقل می رساند.