SQL Injection چیست ؟ چه طور از آن پیشگیری کنیم ؟
«SQL Injection» یا «اسکیوال اینجکشن» یا «تزریق SQL» یکی از روشهای وارد کردن آسیب و هک کردن سایتهای اینترنتی به شمار میرود. این روش هنگامی قابل استفاده است که در طراحی سایت از اصول امنیتی لازم پیروی نشده باشد.
برخی از وبسرورها، برخی از فریمورکها، برخی فایروالها و برخی دیگر از لایههای واسط بین درخواست کاربر و کدهای برنامهنویسی نیز ممکن است بتوانند مانع انجام این نوع حمله شوند.
SQL Injection چه طور اتفاق میافتد ؟
بخش زیادی از فعالیتهای انجام شده در سایتهای اینترنتی، بخشهایی است که کار خواندن و نوشتن اطلاعات از پایگاه داده را انجام میدهند. ارتباط با پایگاه داده معمولا با دستورات SQL انجام میشود که دستوراتی متنی هستند.
قسمتهایی از این دستورات ممکن است توسط کاربر تعیین شوند. برای مثال اگر بخواهیم پایگاه داده اخبار را برای یک عبارت جستجو کنیم، عبارت جستجو را از کاربر دریافت میکنیم.
یک عبارت جستجو روی جدول اخبار میتواند به شکل زیر باشد:
1 |
SELECT * FROM news WHERE title LIKE '%کلمه جستجو%'; |
در کوئری بالا، بخش «کلمه جستجو» از کاربر دریافت میشود. به عبارت دیگر، کاربر هر مقداری را که در فیلد جستجو وارد کند، به پایگاه داده ارسال میشود.
حال فرض کنیم کاربر به جای نوشتن یک کلمه مورد انتظار، عبارت زیر را به عنوان متن جستجو وارد کند:
1 |
%'; DELETE * FROM news; -- |
اگر این عبارت به جای «کلمه جستجو» قرار بگیرد: کوئری ما به این صورت در میآید:
1 2 3 |
SELECT * FROM news WHERE title LIKE '%%'; DELETE * FROM news; -- %'; |
کوئری بالا، تمامی اخبار موجود در پایگاه داده را حذف میکند و مقداری بر نمیگرداند. به عبارت دیگر ما قصد داشتیم متن کاربر را در پایگاه داده جستجو کنیم ولی با یک مشکل امنیتی، تمامی اخبار ما از بین خواهد رفت.
چگونه میتوان مانع عملکرد SQL Injection شد ؟
همان طور که در ابتدا گفته شد، لایههای محافظتی متعددی میتوانند مانع سوء استفاده خرابکاران باشند. در فریمورکهای مدرن برنامهنویسی وب، معمولا این حفاظتها به صورت خودکار انجام میشوند و اگر برنامهنویس از دستورالعملهای توصیه شده پیروی کند، احتمال رخداد این گونه آسیبپذیریها وجود ندارد.
اشکال معمولا زمانی رخ میدهد که برنامهنویس کار ساخت کوئریها را خود انجام دهد یا در محیطهایی مانند وردپرس افزونههایی نوشته شود که نکات امنیتی لازم در آن پیشبینی نشوند.
اگر قصد دارید کوئریهای ارسالی به پایگاه داده را خودتان ایجاد کنید، میبایست عبارتهای دریافت شده از کاربر را با توابعی که بدافزار را پاکسازی میکنند، ایمنسازی نمایید.
دستوری که برای انجام این کار در وردپرس تعبیه شده است، esc_sql نام دارد.
همچنین میتوان از Prepared Statements استفاده نمود. در یک Prepared Statement، کوئری با بخشهایی متغیر تعریف میشود. سپس عبارتهای دریافت شده از کاربر به این متغیرها تخصیص پیدا میکنند. در نتیجه امکان خارج شدن محتوای کاربر از محدودهی متغیر ناممکن خواهد بود. برای مثال کوئری زیر در بخش «?» یک متغیر تعریف کرده است:
1 |
SELECT * FROM news WHERE title = ?; |
سیستمهای ORM در فریمورکهای برنامهنویسی هم از بهترین روشها برای مقابله با SQL Injection به شمار میروند. اغلب فریمورکهای php مانند لاراول نیز به خوبی با این تهدید مقابله میکنند.