یکی دیگر از حملاتی که به وب سایت ها انجام می شود sql injection است. هکر ها با این نوع حمله به راحتی می توانند به اطلاعات مهم شما دست پیدا کرده و از این اطلاعات سئواستفاده کنند. با ما همراه باشید تا در مورد اینکه SQL Injection چیست بیشتر بخوانید و با روش های محافظت در برابر sql injection بیشتر آشنا شوید.
sql injection چیست؟
SQL Injection که در این مقاله از آن به عنوان تزریق به SQL یاد می شود، اغلب برای حمله به وبسایت ها استفاده می گردد. این عمل با استفاده از عبارات SQL در ورودی فرم وب، برای اجرای دستورات SQL برروی پایگاه داده و ارسال این اطلاعات برای مهاجم صورت می گیرد. تزریق به SQL یک تکنیک تزریق کد می باشد که از آسیب پذیریهای نرم افزار وبسایتها استفاده می کند.
آسیب پذیری هنگامی پیش می آید که ورودی کاربر برای کاراکترهای فرّار رشته ای (String Literal Escape Characters) جاسازی شده در عبارات SQL به اشتباه فیلتر شده اند. بنابراین دستورات SQL از طریق فرم وب برای تغییر محتوای پایگاه داده و یا ارسال اطلاعات برای مهاجم، به پایگاه داده یک برنامه تزریق می شوند.
در مورد امنیت پایگاه داده قبلا در مقاله ای دیگر صحبت کرده ایم.
روند حمله sql injection
حملات از طریق تزریق به (SQLIA) یکی از ۱۰ آسیب پذیری برنامه های وب توسط پروژه امنیت برنامه های وب در نظر گرفته شده است. روند حمله با توجه به جنبه های فنی حملات شامل ۵ زیرمجموعه اصلی است :
- حملات کلاسیک از طریق تزریق به SQL
- استنباط تزریق به SQL
- برقراری ارتباط با تزریق به SQL
- حمله به سیستم مدیریت پایگاه داده خاص از طریق تزریق به SQL
- حملات پیچیده از طریق تزریق به SQL
- تزریق به SQL + احراز هویت ناکافی
- تزریق به SQL + حملات DDoS
- تزریق به SQL + ربودن DNS
پیاده سازی فنی حمله sql injection
بررسی اشتباه کاراکترهای فرّار
این نمونه از تزریق به SQL هنگامی رخ می دهد که ورودی کاربر برای کاراکترهای فرّار فیلتر نشده اند و سپس به یک عبارت SQL منتقل می شوند. نتیجه این عمل دستکاری مؤثر عبارات در پایگاه داده توسط نرم افزار سمت کاربر است.
نمونه کد زیر نموه ای از این آسیب پذیری را نشان می دهد :
[pre]
statement <span>=</span> <span>”SELECT * FROM users WHERE name = ‘”</span> <span>+</span> userName <span>+</span> <span>”‘;”</span>
[/pre]
این کد SQL جهت دسترسی به رکورد نام کاربری مشخص ، از جدول کاربران می باشد. اما ، اگر متغیر “username” در یک مسیر مشخص توسط یک کاربر مخرب دستکاری شود ، ممکن است عبارت SQL ، بیش از آنکه طراح کد درنظر دارد تغییرات انجام دهد. به عنوان مثال ، متغیر “username” را به این شکل تنظیم می نماییم :
[pre]
' or '1'='1
[/pre]
و یا از کارکترهای SQL برای جلوگیری از پرس و جوهای اضافی استفاده می نماییم :
[pre]
' or '1'='1' -- '
' or '1'='1' ({ '
' or '1'='1' /* '
[/pre]
اگر این کد در یک رویه احراز هویت مورد استفاده قرار گیرد ، از این پس می توان از آن برای انتخاب یک نام کاربری معتبر اجباری استفاده کرد ، زیرا نتیجه ‘۱’=’۱′ همیشه درست است.
مقدار زیر برای “username” ، در عبارت زیر موجب حذف جدول “users” می شود.
[pre]
a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't
[/pre]
عبارت نهایی SQL این ورودی به شکل زیر است :
[pre]
<span>SELECT</span> <span>*</span> <span>FROM</span> users <span>WHERE</span> name <span>=</span> <span>'a'</span>;<span>DROP</span> <span>TABLE</span> users; <span>SELECT</span> <span>*</span> <span>FROM</span> userinfo <span>WHERE</span> <span>'t'</span> <span>=</span> <span>'t'</span>;
[/pre]
در حالی که اکثر سرورهای SQL ، اجازه اجرای عبارات متعدد با یک فراخوانی توسط این راه را می دهند ، بعضی از برنامه های کاربردی SQL مانند دستور ()mysql_query در PHP به دلایل امنیتی این اجازه را نمی دهند.
محافظت در برابر sql injection
از سایت خود در برابر تزریق SQL محافظت کنید ، هیچ راه حلی همه مسائل را حل نمی کند. اما یک سری دیوار های کوچک با یکدیگر تشکیل دیواری قدرتمند را می دهند. حداقل دیوارهای لازم جهت جلوگیری از مهاجمین :
- ۱. از نامهای اصلی و سخت برای نام جداول و ستونها استفاده کنید تا قابل حدس زدن نباشند.
این واقعیتی است که هر شخصی نام جدول کاربران خود را “users” می نامد و این می تواند دلیل بزرگی باشد برای این که چرا شما این کار را انجام ندهید. اگر یک سایت شخصی دارید ، آنرا با هر عنوانی می توانید بسازید ، اما برای یک مجموعه بزرگ بهتر است متفاوت باشد :
Table: user_Details
Columns: u_uID,u_user_Name,u_user_Password etc
- ۲. از نامهای مستعار استفاده کنید.
مثال زیر را درنظر بگیرید :
SELECT s.sID,s.title,s.blu rb,s.story,a.aName,a.aNationality,a.aAge FROM story s,
author a WHERE sID=3 AND a.aID=s.aID
با این مثال مقایسه کنید :
SELECT story.sID, story.title, story.blurb, story.story, author.aName,
author.aNationality, author.aAge FROM story s, author a WHERE sID=3 AND
author.aID= story.aID
اگر یک مهاجم این دستور را بشکند ، در انتها با یک پیغام خطا مواجه می شود. کدامیک اطلاعات بیشتری به مهاجم می دهد؟ هنگامی که شما از نام های مستعار استفاده می کنید ، کوتاه شده آنها را بکار گیرید (s به جای story). اینکار باعث می شود مهاجم به اطلاعات ناقص دست یابد.
- ۳. در هر فرم محدودیت طول تنظیم کنید و از نامهای واقعی برای ستونها استفاده نکنید.
اگر سایت شما صفحه ورود کاربران داشته باشد ، دوگزینه برای ورود وجود دارد : ۱- نام کاربری ۲- رمز ورود
این دو را به یک شماره واقعی محدود کنید.
<input type=”text” name=”member_name” size=”۱۲″ maxlength=”۶۰”>
<input type=”text” name=”member_pa ssword” size=”۱۲″ maxlength=”۶۰”>
نام واقعی ستون را برای فیلد نام ها استفاده نکنید ، زیرا کار برای مهاجم آسان می شود. در قطعه کد بالا ، مهاجم ستونهای “u_user_Name” و “u_user_Password” را در جدول “user_Details” تطبیق می دهد.
- ۴. حداقل اعتبار را برای اطلاعات خود در سمت سرور برای محتوا ، طول و قالب تنظیم کنید.
اعتبار سنجی باید همیشه در سمت سرور انجام شود. چک کردن داده ها با جاوا اسکریپت در سمت کاربر وقت تلف کردن است. همه مهاجمین نیاز به دانلود صفحه شما به صورت فایل html دارند ، جاوا اسکریپت را حذف کرده و آن را از سیستم خودشان اجرا کنید.
از یک اعتبار اسکریپت برای کل سایت استفاده نکنید. اطلاعات مختلف نیازمند اعتبار سنجی مختلف هستند. به عنوان مثال اعتبارسنجی برای “username” با “story ID” متفاوت خواهد بود.
- ۵. اگر از محصولی استفاده می کنید که سورس کد آن در دسترس است ، آنرا در رابطه با آسیب پذیری ها به روز نگه دارید.
اگر شما از یک نرم افزار متن باز ارسال پیام استفاده می کنید ، یک مهاجم همانند شما می تواند سورس کد را دانلود کند و به دنبال نقاط ضعف آن بگردد. به طور مداوم نقاط آسیب پذیر نرم افزار را بررسی کرده و آنها را در جهت حفظ امنیت به روز رسانی کنید.
- ۶. طرح خود را منحصر به فرد کنید. به عنوان مثال اگر اجازه ایجاد نام جدول داده شده است مطمئن شوید که تغییرات از پیش فرض سایت متمایز باشد.
در صورت امکان طرح خود را از مدل پیش فرض آن متمایز کنید. کدهای خود را مطالعه کنید و مطمئن شوید که هیچ حفره آشکاری وجود ندارد.
- ۷. در صورت امکان از رویه های ذخیره شده استفاده کنید.
رویه های ذخیره شده یک راه بسیار خوب برای کاهش احتمال حمله از طریق تزریق SQL هستند. به هر حال به عنوان کسی که آنها را می نویسد در استفاده از پارامترها در همه زمانها مطمئن باشید.
با این حال اگر از رویه های ذخیره شده استفاده می کنید باید داده های خود را از قبل اعتبارسنجی کنید.
- ۸. کدهای سایت را بررسی کنید.
هیچ کس کد کاملی نمی نویسد. اعضای یک تیم باید کد یکدیگر را مطالعه کنند تا احتمال وجود نقص در کدها کاهش یابد.
- ۹. سرور خود را امن نمایید.
روش های زیر را در سرور اعمال کنید :
الف – حداقل دسترسی برای کابران
ب – حذف حسابهای غیرضروری
پ – حذف یا غیرفعال کردن رویه های ذخیره شده غیرضروری و توسعه یافته
ت – حذف اطلاعات غیرضروری
ث – به روز رسانی
پردازش هایی که لازم است روی داده ها اعمال شود:
- الف – حذف علامت (‘)
اگر این عمل امکان پذیر نیست آنها را دو برابر کنید و مانند مثال زیر از دستور جایگزینی استفاده کنید :
function quotehandle(data)
quotehandle=replace(data,”‘”,”””)
end function
- ب – حذف علامتهای (;) و (–)
function sqldash(data)
sqldash=replace(data,”–“,””)
end function
function sqlcolon(data)
sqlcolon=replace(data,”;”,””)
end function
- پ – بررسی نوع داده ها
اگر شما در انتظار یک عدد صحیح هستید ، بررسی کنید که آیا ورودی یک عدد صحیح است. اگر اینطور نیست آن را رد کنید.
- ت – تنظیم نوع داده ها
تقویت مرحله قبل و تنظیم نوع داده ها به طور صریح
storyID=CInt(request(“storyID”))
authorname=CStr(request(“authorname”))
- ث – اعتبارسنجی داده ها
مطمئن شوید که داده ها صحیح هستند.
- ج – بررسی طول داده ها
طول داده ها را بررسی کنید. اگر بیش از حد طولانی است آن را کوتاه کنید. به عنوان مثال اگر شما انتظار میزبانی بیش از ۱۰۰۰۰ شعر در سایت خود را دارید ، “poemID” نیازی نیست بیش از ۴ کارکتر باشد. تابع زیر ، یک مثال ساده از نحوه انجام این کار است :
data=left(data,4)
و برای داده های طولانی تر :
data=left(data,125)