حمله SQL Injection که با نام تزریق SQL نیز شناخته میشود، یکی از قدیمیترین و خطرناکترین تهدیدات امنیتی وب است که به مهاجمان امکان استخراج یا دستکاری دادههای پایگاه داده را میدهد. بسیاری از برنامههای وب به دلیل ورودیهای ناامن، در برابر این حمله آسیبپذیر هستند که میتواند منجر به افشای اطلاعات حساس، خسارات مالی و خدشه به اعتبار سازمانها شود. در این مقاله، نحوه عملکرد تزریق SQL، انواع آن و روشهای پیشگیری را بررسی خواهیم کرد.
حمله تزریق SQL چیست؟
پیش از بررسی حمله SQL Injection، بهتر است ابتدا با پایگاه دادههای رابطهای و زبان SQL آشنا شویم. پایگاه داده رابطهای، سیستمی برای مدیریت دادهها در قالب جداول مرتبط به هم است که به دلیل قابلیت اطمینان بالا و پردازش کارآمد تراکنشها، در بسیاری از سامانههای تجاری مورد استفاده قرار میگیرد.
SQL که مخفف «Structured Query Language» به معنای زبان پرسوجوی ساختیافته است، زبانی استاندارد برای تعامل با پایگاه دادههای رابطهای محسوب میشود. استانداردهای SQL توسط سازمان ISO تعیین میشود. در نتیجه، پایگاه دادههای رابطهای، علیرغم تفاوت در پیادهسازی توسط شرکتهای مختلف، همگی از اصول مشترکی پیروی میکنند.
حمله SQL Injection یا به اختصار (SQLi)، نوعی آسیبپذیری است که به مهاجمان امکان وارد کردن کدهای SQL مخرب را از طریق ورودیهای کاربر داده و به طور مستقیم پایگاه داده را تحت تأثیر قرار میدهد. این مشکل اغلب به دلیل عدم بررسی صحیح ورودیهای کاربر رخ میدهد و در سیستمهایی که از کوئری پویا (Dynamic Query که در زمان اجرای برنامه ساخته میشود) استفاده میکنند، خطر آن بیشتر است.
خطرات تزریق SQL گسترده است و میتواند خسارات زیادی به بار آورد. یک نمونه واقعی در سال ۲۰۲۳ توسط گروه هکری ResumeLooters رخ داد که بیش از ۲.۱ میلیون رکورد کاربری را از سایتهای کاریابی و خردهفروشی در منطقه آسیا-اقیانوسیه سرقت کرد و در تلگرام به فروش رساند. این مثال نشان میدهد که حتی کوچکترین سهلانگاری در برنامهنویسی وب میتواند به نتایج فاجعهآمیز منجر شود، و بنابراین محافظت در برابر این حملات برای کسبوکارها ضروری است.
حمله SQL Injection چگونه انجام میشود؟
هسته اصلی حمله SQL Injection، دستکاری در «اطلاعات ورودی کاربرانی» است که به درستی اعتبارسنجی نشدهاند. در این حمله، مهاجم به جای وارد کردن دادههای معمولی در فرم ورودی، دستورات مخرب SQL را ارسال میکند. این دستورات به عنوان بخشی از پرسوجوی پایگاهداده اجرا میشوند و میتوانند منجر به نشت اطلاعات، تغییر دادهها یا حتی اجرای دستورات غیرمجاز شوند. زمانی که کوئری آلوده به پایگاهداده ارسال میشود، سیستم ابتدا به دنبال نام کاربری معتبر میگردد، اما شرط اضافی که مهاجم تزریق کرده، باعث میشود که بررسی رمز عبور همیشه صحیح باشد. این امر موجب میشود که سیستم بدون اعتبارسنجی مناسب، دسترسی غیرمجاز به مهاجم بدهد تا اطلاعات حساس را بخواند، دادهها را تغییر دهد، عملیات مدیریتی را اجرا کند و حتی در برخی موارد، دستورات اجرایی روی سیستمعامل سرور انجام دهد.
برای درک بهتر، فرض کنید که یک سیستم پایگاهداده از شناسه کاربری به عنوان ورودی استفاده میکند. در صورتی که این مقدار با یکی از رکوردهای پایگاهداده مطابقت داشته باشد، اطلاعات مرتبط را بازمیگرداند. حال اگر یک مهاجم مقدار ورودی را بهگونهای تغییر دهد که همیشه شرط درست باشد، میتواند بدون احراز هویت وارد سیستم شود. برای مثال، با وارد کردن عبارت ‘OR ‘1’=’1 ‘ ‘
در فیلد نام کاربری یا پسورد، پایگاه داده بر اساس شرط جستجو به دنبال کاربری میگردد که نام کاربری یا رمز عبور آن خالی باشد یا شرط ۱=۱ برقرار باشد. چون شرط ۱=۱ همیشه برقرار است پایگاه داده تشخیص میدهد این کاربر وجود دارد و معتبر است و به مهاجم اجازه ورود میدهد.
انواع حمله تزریق SQL
حمله تزریق SQL بر اساس نحوه اجرا، روش استخراج دادهها و میزان وابستگی به خطاهای پایگاهداده به انواع مختلفی تقسیم میشوند.
۱. تزریق SQL مبتنی بر خطا (Error-Based SQL Injection)
در حمله به روش Error-Based SQL Injection، مهاجم با وارد کردن ورودیهای نامعتبر، تلاش میکند که پایگاهداده را وادار به تولید پیامهای خطا کند. این پیامها معمولاً شامل اطلاعاتی درباره ساختار پایگاهداده، نام جداول، ستونها و سایر جزئیات فنی هستند. هرچند این روش معمولاً بهطور مستقیم موجب افشای دادههای حساس نمیشود، اما اطلاعات بهدستآمده میتوانند به مهاجم کمک کنند تا حملات موثرتر و پیچیدهتری را برنامهریزی کند.
۲. تزریق SQL مبتنی بر UNION ها (UNION-Based SQL Injection)
در حمله به روش UNION-Based SQL Injection، از عملگر UNION در SQL برای ترکیب چندین عبارت SELECT استفاده میشود. با استفاده از این عملگر، مهاجم تلاش میکند تا یک کوئری اضافی را از طریق UNION به پرسوجوی اصلی برنامه اضافه کند و از این طریق، دادههای غیرمجاز را بازیابی کند. در صورتی که برنامه، بهدرستی اعتبارسنجی ورودی را انجام ندهد، مهاجم میتواند به اطلاعات حساس ذخیرهشده در جداول مختلف پایگاهداده دسترسی پیدا کند.
۳. تزریق SQL کور (Blind SQL Injection)
در شیوه حمله Blind SQL Injection، مهاجم هیچ خروجی مستقیمی از پایگاهداده دریافت نمیکند، بلکه با تحلیل رفتار برنامه و تفاوت در پاسخها، اطلاعات را استخراج میکند. تزریق SQL کور به دو روش اصلی انجام میشود:
- تزریق مبتنی بر شرط بولی (Boolean-Based Blind SQL Injection) که مهاجم با ارسال شرطهای منطقی مختلف، تغییرات در رفتار برنامه را بررسی میکند. اگر برنامه بر اساس مقدار ورودی، رفتار متفاوتی نشان دهد (مثلاً نمایش یا عدم نمایش یک صفحه)، مهاجم میتواند وجود یا عدم وجود دادههای خاصی را استنتاج کند.
- تزریق مبتنی بر زمان (Time-Based Blind SQL Injection) که مهاجم از دستورات تأخیری SQL مانند Sleep استفاده میکند. اگر پایگاهداده در پاسخ به یک ورودی خاص، مدت زمان بیشتری برای پاسخگویی نیاز داشته باشد، مهاجم متوجه میشود که شرط تزریقشده، اجرا شده و پرسوجو معتبر بوده است.
۴. تزریق SQL خارج از باند (Out-of-Band SQL Injection)
از روش حمله Out-of-Band SQL Injection زمانی استفاده میشود که مهاجم نتواند از پاسخهای مستقیم پایگاهداده استفاده کند. در این حالت، اطلاعات از طریق یک کانال ارتباطی دیگر مانند درخواستهای DNS یا HTTP به سرور کنترلشده توسط مهاجم ارسال میشود. این روش معمولاً زمانی موثر است که پایگاهداده به اینترنت متصل باشد و امکان ارسال درخواستهای خارجی را داشته باشد.
۵. تزریق SQL مرتبه دوم (Second-Order SQL Injection)
در حملهبه شیوه Second-Order SQL Injection ، مهاجم کد مخرب را در پایگاهداده ذخیره میکند تا در آینده، در یک عملیات دیگر و بهصورت غیرمستقیم اجرا شود. این نوع تزریق معمولاً در فرمهای ورودی، سیستمهای ثبت اطلاعات کاربران یا فیلدهای ذخیرهشده در پایگاهداده رخ میدهد. از آنجایی که اجرای این کد در زمانی دیگر و توسط فرآیندی متفاوت انجام میشود، تشخیص آن دشوارتر است و میتواند منجر به تغییرات مهمی در تنظیمات یا دادههای پایگاهداده شود.
تشخیص و شناسایی حمله SQL Injection
در صورتی که سیستم شما در معرض حمله تزریق SQL قرار گیرد، علائم هشداردهندهای وجود دارند که میتوانند نشاندهنده وقوع چنین حملهای باشند. برای تشخیص آسیبپذیریها و شناسایی حمله تزریق SQL، میتوانید از روشهای مختلفی استفاده کنید که شامل ابزارهای شناسایی خودکار، روشهای دستی و تست نفوذ است. برخی از علائمی که میتوانند نشاندهنده وجود حمله SQL Injection عبارتند از:
- نمایش پیامهای خطای غیرعادی یا اطلاعات حساس از پایگاهداده.
- هدایت تبلیغات به وبسایتهای مشکوک یا مخرب.
- دریافت حجم زیادی از درخواستها در مدت زمان کوتاه، مانند دریافت تعداد زیادی ایمیل از فرمهای تماس.
ابزارهای شناسایی حمله SQL Injection
ابزارهای اسکن خودکار: ابزارهای اسکن خودکار برای شبیهسازی حمله تزریق SQL طراحی شدهاند تا پاسخهای برنامه را تحلیل کنند و نقاط ضعف احتمالی را شناسایی کنند. این ابزارها معمولاً برای اسکن سریع و شناسایی آسیبپذیریهای رایج مناسب هستند.
تست دستی: در صورتی که اسکن خودکار نتواند آسیبپذیریهای پیچیدهتری را شناسایی کند، بررسی دستی کد میتواند دقیقتر عمل کند. این کار توسط متخصصان امنیت انجام میشود و شامل بررسی ورودیهای برنامه و کدهای آن برای یافتن مشکلات امنیتی است.
تست نفوذ: تست نفوذ (Penetration Testing) شامل شبیهسازی حملات واقعی توسط هکرهای اخلاقی است که بهطور مستقیم به سیستمها حمله کرده و آسیبپذیریها را شناسایی میکنند. این روش یک ارزیابی دقیقتر و واقعگرایانه از سیستم شما را ارائه میدهد و میتواند مشکلاتی را که ابزارهای اسکن خودکار قادر به شناسایی آنها نیستند، آشکار کند. اگرچه تست نفوذ مؤثر است، اما معمولاً زمانبر و پرهزینه است. در مقالههای قبل به طور کامل به بررسی راهکار تست نفوذ پرداختهایم.
برخی از ابزارهای کاربردی برای شناسایی حمله تزریق SQL به شرح زیر هستند:
نام | نوع | ویژگی | کاربرد |
SQLMap | متنباز | شناسایی و تست پیشرفته حمله تزریق SQL، پشتیبانی از پایگاهدادههای مختلف | تست نفوذ و ارزیابی آسیبپذیری |
jSQL Injection | متنباز | شبیهسازی حمله SQL Injection، شناسایی آسیبپذیریها | تست نفوذ و ارزیابی آسیبپذیری |
Imperva SQL Injection Protection | تجاری | نظارت بلادرنگ، مسدود کردن فعالیتهای مخرب، گزارشدهی حملات | حفاظت و نظارت امنیتی |
AppSpider | تجاری | تست امنیت با رابط کاربری بصری، شناسایی آسیبپذیریهای تزریق SQL | تست نفوذ و ارزیابی آسیبپذیری |
Acunetix | تجاری | اسکن آسیبپذیریهای وب، شناسایی تزریق SQL، رابط کاربری کاربرپسند | اسکن آسیبپذیریهای وب |
چگونه از حمله تزریق SQL جلوگیری کنیم؟
برای جلوگیری از حمله تزریق SQL، اقدامات مختلفی در سطوح پایگاهداده و برنامه قابل پیادهسازی هستند.
۱. اقدامات در سطح پایگاهداده
- محدود کردن مجوزهای کاربران: در هنگام تنظیم پایگاهداده، سطح دسترسی کاربران به حداقل رسانده شود. فقط کاربران با نیازهای خاص باید دسترسی به عملیات حساس مثل حذف یا تغییر دادهها داشته باشند.
- استفاده از دستورات آماده: استفاده از دستورات آماده (Prepared Statements امکان اجرای چندباره دستورات مشابه SQL است که برای افزایش کارایی استفاده میشود) که با نام کوئریهای پارامتریشده (Parameterized Query) نیز شناخته میشود، بهترین روش برای جلوگیری از تزریق SQL است. در این روش، کد SQL بهطور جداگانه نوشته میشود و ورودیهای کاربر بهعنوان دادهها در نظر گرفته میشوند.
۲. اقدامات در سطح برنامه
- استفاده از Placeholderها: با استفاده از Placeholderها در عبارات SQL، مقادیر ورودی بهطور خودکار به عبارت SQL وارد میشوند. این کار باعث میشود تا مهاجمان نتوانند از ورودیهای نامعتبر برای دستکاری SQL استفاده کنند.
- پنهان کردن پیامهای خطا: پیامهای خطای نمایش دادهشده میتوانند اطلاعات زیادی در مورد ساختار پایگاهداده یا کد برنامه به مهاجم بدهند. این پیامها باید بهطور مناسب پنهان یا مدیریت شوند.
- استفاده از ابزارهای نظارتی و فایروال برنامه وب (WAF): ابزارهای WAF میتوانند ترافیک مخرب را شناسایی کرده و از رسیدن آن به سیستم شما جلوگیری کنند. برای آشنایی با این ابزار، مقاله WAF چیست از آبالون را مطالعه بفرمایید.
۳. تکنیکهای پیشرفته
- اعتبارسنجی ورودی: تمام دادههای ورودی از کاربران باید بهدقت اعتبارسنجی شوند. برای مثال، مطمئن شوید که دادهها مطابق با فرمتهای از پیش تعیینشده هستند (مثلاً فقط اعداد در فیلدهای خاص).
- اصل حداقل دسترسی: به هر کاربر فقط دسترسیهای لازم برای انجام کارهای خود اعطا کنید. این کار امکان سوءاستفاده را به حداقل میرساند.
- پالایش دادهها (Sanitization): برای جلوگیری از تزریق SQL، ورودیهای کاربر باید پالایش شوند تا کاراکترهای خاص که میتوانند باعث اجرای دستورات SQL مخرب شوند، حذف شوند.
- تفکیک دادهها: دادهها باید در پایگاهدادهها و سرورهای مختلف ذخیره شوند تا در صورت نفوذ به یک پایگاهداده، دسترسی به تمام دادهها محدود شود.
جمعبندی
در این مقاله از بلاگ آبالون، به بررسی حمله تزریق SQL و روشهای جلوگیری از آن پرداختیم. ابتدا توضیح دادیم که تزریق SQL چگونه میتواند به پایگاهدادهها آسیب بزند و سپس به بررسی تکنیکهای مؤثر برای پیشگیری از این نوع حملات پرداختیم. استفاده از دستورات آماده و پرسوجوهای پارامتریشده، اعتبارسنجی ورودیها، محدود کردن دسترسیها، و استفاده از فایروالهای برنامه وب (WAF) از جمله روشهای مؤثری هستند که میتوانند به طور قابل توجهی امنیت پایگاهدادهها را افزایش دهند. با رعایت این اقدامات، میتوانید سیستم خود را در برابر حمله SQL Injection ایمن نگه دارید و از دادههای حساس خود محافظت کنید.