برای ایجاد امنیت در نرم افزار، باید ابتدا مشکلات رایج را بدانیم. یکی از رایجترین نقائص امنیتی نرم افزارها SQL Injection میباشد.
SQL Injection در لغت به معنی تزریق کد SQL میباشد. در اصلاح یعنی تزریق دستوراتی به کد SQL تولیدی یک نرم افزار به نحوی که به جای عمل مورد انتظار برنامه نویس آن، کاری را که ما میخواهیم انجام دهد. مثلا به جای اینکه هنگام ورود به برنامه وقتی کاربر مشخصات کاربری خود را وارد میکند، مشخصات کاربری را به نحوی وارد کنیم که بتوانیم بعنوان مدیر سامانه و یا یک کاربر معمولی بدون داشتن کلمه عبور وارد سیستم شویم.
البته همیشه از این نوع حمله برای ورود به سیستم استفاده نمیشود. یعنی ممکن است هکر به عنوان یک کاربر عادی وارد سیستم شود ولی با به کاربردن دستورات خاص SQL در بخشهای مختلف، بتواند اطلاعاتی را حذف نماید.
خوب حالا این کار چگونه انجام میشود؟
فرض کنید برنامه نویسی کد چک نام کاربری را اینگونه نوشته باشد:
SqlCommand cmd=new SqlCommand ("select count(*) from login where user='"+userName+"' and pass='"+password+"'",con);
فکر نکنید خوب این نوع کد نویسی مربوط به زمان تیرکمون شاه است! همین امروز در نظارت از یک پروژه به این نکته برخورد کردم! دلیل نوشتن این مقاله هم همین کد بود.
خوب حالا مگر کد بالا چه مشکلی دارد؟ ;) اگر کاربر در نامه کاربری و کلمه عبور مقادیر معمولی وارد کند (مانند admin, salam123) کد sql تولید شده به شکل زیر خواهد بود:
select count(*) from login where user='admin' and pass='salam123'
خوب حالا اگر کاربر کمی با ورودیها بازی کند. به عنوان مثال فرض کنید به جای کلمه عبور تایپ کند
نتیجه حاصله خواهد بود:
select count(*) from login where user='admin' and pass='' or 1=1 --'
با وارد کردن این دستور کاربر بدون داشتن کلمه عبور خواهد توانست وارد سیستم شود. موردی که توضیح دادم پایه مسئله بود. ما قصد آموزش هک نداریم ولی داشتن اطلاعات پایه لازم است. ممکن است فردی بگوید خوب ما قبل از تولید همچین کدی ' را از رشته کلمه عبور حذف میکنیم. خیلی خوب ولی اگر هکر از معادل unicode آن استفاده کرد چه؟ اگر و اگر و اگر...
راه حلهای متعددی برای این موضوع پیشنهاد شده است. ولی سادهترین و کارآمدترین راه، استفاده از پارامترها میباشد که علاوه بر حذف این خطر باعث ایجاد و ذخیره query plan در sql server میشود و اجرای این query را در آینده تسریع میکند.
بنابراین میتوان کد فوق را به صورت زیر بازنویسی کرد:
SqlCommand cmd=new SqlCommand ("select count(*) from login where user=@u and pass=@p",con);
cmd.Parameters.Add("@u", SqlDbType.Varchar, 10).Value=TextLogin.Text.Trim();
cmd.Parameters.Add("@p", SqlDbType.Varchar,10).Value=TextPwd.Text.Trim();