آشنايي با SQL Injection (بخش نخست) چگونه از برنامه خود در برابر هكرها محافظت كنيم با گذشت بيش از ده سال از حمله به پورت هاي باز و سرويس هاي رخنه پذير توسط مهاجمين، امروزه مديران سيستم با نصب ديواره هاي آتش و انجام برخي موارد امنيتي، تنها امكان مشاهده برخي سرويس هاي ضروري را فراهم مي كنند كه بسياري از اين سرويس ها هم پچ شده و غيرقابل نفوذ هستند. بنابراين امروزه مهاجمين سيستم هاي رايانه اي، استراتژي خود را از تهاجم به سيستم عامل به سوي تهاجم عليه برنامه هاي در حال اجرا روي سيستم عامل ها تغيير داده اند. آنچه مسلم است انگيزه اصلي اين افراد در سرقت اطلاعات، سرويس ها و به طور كلي هر آنچه منفعتي براي ايشان ايجاد كند تمركز يافته است.
بي گمان برنامه نويس با آگاهي از تهديدهاي موجود مي تواند اقدام به ايمن سازي برنامه خود در برابر حملات مخرب كند. در اين مقاله كوشش شده است تا برخي روش هاي رايج نفوذ و تخريب برنامه هاي تحت وب معرفي شود.
سه كوئل اينجكشن
در اين تكنيك، مهاجم با تزريق دستورات SQL مورد نظر خود در كنار دستورات اصلي برنامه،اقدام به تخريب لايه ديتاي برنامه مي كند. در صورتي كه اين عمل با موفقيت انجام شود، مهاجم قادر به بازيابي، تغيير و يا حذف اطلاعات ذخيره شده در بانك اطلاعاتي خواهد بود.
با ارايه چند مثال به بررسي عملي اين تكنيك مي پردازيم:
صفحه وبي را در نظر بگيريد كه براي انجام عملياتي خاص، اقدام به دريافت شماره شناسايي از كاربر مي كند. در صورتي كه كاربر اقدام به تايپ شماره "1234" در فيلد مورد نظر كند، دستور زير به بانك اطلاعاتي ارسال خواهد شد:
SELECT A,B
FROM testTable
WHERE id = 1234
در نتيجه دستور فوق، فيلدهاي Aو B كه شماره شناسايي آنها "1234" است، از جدول testTable انتخاب خواهند شد.
حال در صورتي كه مهاجم اقدام به تايپ عبارت "1234 OR 1=1" در فيلد فوق كند، دستور SQL به شكل زير ارسال خواهد شد:
SELECT A,B
FROM testTable
WHERE id = 1234 OR 1=1
از آنجا كه "1=1" موجود در قسمت شرطي دستور SELECT فوق همواره برقرار است، اين عبارت منجر به خنثي شدن قسمت شرطي دستور شده و معادل با دستور زير خواهد بود:
SELECT A,B
FROM testTable
همان طور كه مشخص است، در نتيجه اين دستور تمام ركوردهاي موجود در جدول انتخاب خواهد شد.
بنابراين مهاجم در اين بخش با آگاهي وسيع از دستورات، با قرار دادن دستور مورد نظر خود در كنار دستور اصلي برنامه، به جاي انتخاب ركورد مرتبط با شماره شناسايي خود، اقدام به مشاهده تمام ركوردهاي جدول كرده است.
اين آسيب پذيري مي تواند بسيار مخرب تر از مورد بالا باشد. براي مثال فرض كنيد اطلاعات مربوط به كاربران در جدولي بنام users ذخيره شده باشد:
حال در صورتي كه مهاجم عبارت "1234; DROP TABLE users" را در فيلد شماره شناسايي وارد سازد، دستور SQL زير اجرا خواهد شد:
SELECT A,B
FROM testTable
WHERE id = 1234; DROP TABLE users;
دستور فوق متشكل از دو دستور SQL است كه دستور اول براي انتخاب فيلدهاي Aو B از جدول testTabe است، اما دستور دوم صرف نظر از دستور اول، منجر به حذف جدول users خواهد شد. بي شك در پي اين حمله، ورود كاربران به سيستم مختل خواهد شد.
حال به بررسي روش هاي معمول در مقابله با سه كوئل اينجكشن مي پردازيم:
* اعتبارسنجي مقادير با تعيين نوع و تعداد كاراكترهاي مجاز، انتخاب نوع داده اي مناسب و تعيين دامنه معتبر براي فيلدها.
در صورتي كه فيلد مورد نظر در برگيرنده مقادير عددي است، از پذيرش حروف و نشانه اجتناب كنيم.
نسبت به كاراكترها، نشانه ها و واژگان وارد شده توسط كاربر، به ويژه در موارد كلمات و نشان هاي مورد استفاده در دستورات SQL، حساسيت نشان دهيم.
انتخاب نوع داده اي مناسب در ساختار تشكيل دستور SQL :
"SELECT A,B FROM testTable
WHERE id = " + testVariable + ";"
در اينجا مقدار متغير testVariable به عنوان مقدار id در نظر گرفته مي شود. حال اگر مقدار id از نوع عددي باشد، انتخاب نوع داده رشته اي براي متغير testVariable منجر به افزايش آسيب پذيري برنامه خواهد شد، چراكه در اين صورت كاربر مجاز به وارد كردن هر تركيبي از كاراكترها علاوه بر اعداد است.
* استفاده از حساب كاربري مشخص با سطح دسترسي محدود در اجراي دستورات بانك اطلاعاتي.
* استفاده از پارامترها و رويه هاي ذخيره شده در بانك اطلاعاتي.
در اين صورت پارامترها از نظر نوع ارسال شده و طول مجاز بررسي مي شوند، همچنين مقادير ارسالي از نوع دستورات اجرايي در نظر گرفته نمي شوند.
* و سرانجام، پرهيز از نمايش صريح خطاهاي موجود در اجراي دستورات به كاربر.