sql injection چیست؟
یادداشت ویراستار: این مطلب در آبان 1400 توسط کارشناسان سرور و شبکه فالنیک، بررسی و تایید شده است.
در این مقاله sql injection را بررسی میکنیم و درباره نتایج این حمله، انواع و روشهای مقابله با آن صحبت میکنیم.
- injection چیست؟
- مفهوم sql injection چیست؟
- تاثیرات حمله sql injection موفق چیست؟
- انواع sql injection
- جلوگیری از حمله sql injection
injection چیست؟
حملات injection به دستهای از حملات و هکها گفته میشود که در آن مهاجم، ورودی غیرقابل اعتماد وارد برنامه میکند. این ورودیها روی بخشی از دستور یا کوئری تاثیر میگذارد و اجرای آن برنامه را تغییر میدهد.
حملات injection قدیمیترین و خطرناکترین حمله به برنامههای وب است که منجر به دزدی اطلاعات، گم شدن اطلاعات، و از دست رفتن یکپارچگی اطلاعات میشود. بیشتر آسیبهای اینجکشن، تایید اعتبار ورودی نامناسب کاربر است.
برخی از انواع حملات injection عبارتند از:
- Code injection
- CRLF injection
- Cross-site Scripting (XSS)
- Email Header Injection
- Host Header Injection
- LDAP Injection
- OS Command Injection
- XPath injection
- SQL Injection (SQLi)
مفهوم sql injection چیست؟
حالا ببینیم باگ sql چیست. sql injection یا sqli آسیب امنیتی وب است که به هکر اجازه مداخله در کوئری های دیتابیس را میدهد. مثلا هکرها دیتایی که در حالت عادی دسترسی به آن نیست را میبینند. ممکن است دیتایی باشد که متعلق به کس دیگری است یا دیتایی باشد که فقط خود برنامه امکان دسترسی به آن را دارد. در بسیاری موارد مهاجم این دیتا را پاک میکند یا تغییر میدهد در نتیجه روی محتوا و یا رفتار برنامه تاثیر میگذارد.
هر وب سایت و برنامه وبی که از دیتابیس sql مثل MySQL و Oracle و SQL Server استفاده میکند در معرض آسیب این حمله است. Sql زبان کوئریها است که برای مدیریت اطلاعات ذخیره شده در دیتابیسها طراحی شده است. پس با استفاده از آن میتوان دسترسی و اصلاح و حذف اطلاعات را انجام داد. حتی میتوان از دستورات sql برای اجرای برخی دستورات سیستم عاملی استفاده کرد. در نتیجه حمله sql injection موفق، عواقب زیادی دارد.
نکته مهم این است که باگ sql اصلا به دلیل ضعف sql نیست بلکه برنامهنویسها با اشتباهات برنامهنویسی راه را برای هکرها و انجام تزریق sql هموار میکنند.
هکر ابتدا به دنبال ورودیهای کاربری آسیبپذیر در صفحه وب یا برنامه وب میگردد چون بدین ترتیب میتواند مستقیم وارد کوئری sql شود. هکر، محتوای ورودی که malicious payload نامیده میشود و کلید اصلی حمله است را آماده میکند. پس از اینکه هکر این محتوا را وارد میکند، دستورات SQL مخرب در دیتابیس اجرا میشود.
در SQL Injection امکان اجرای SQL statement های مخرب فراهم میشود. این استیت منتها کنترل دیتابیس سرور پشت برنامه وب را به دست میگیرند. هکرها از SQLi استفاده میکنند تا به صفحه وب، برنامه وب و بازیابی محتوای کل دیتابیس sql دست یابند تا بتوانند رکوردهای دیتابیس را اضافه و اصلاح و حذف کنند.
تاثیرات حمله sql injection موفق چیست؟
برخی مواقع مهاجم از انواع حملات sql injectionاستفاده میکند تا سرور و دیگر زیرساختها را از سرویس خارج کند یا حمله دایس – DoS انجام دهد. همچنین دسترسی به سیستم عامل باعث میشود هکر بتواند به شبکه داخلی شما نفوذ کند. برای استفاده از خدمات تعمیر سرور hp و ارتقای آن روی لینک بزنید.
یک حمله موفق sql injection دسترسی کامل به تمام اطلاعات دیتابیس سرور را به هکر میدهد و روی دسترسیهای غیرمجاز به اطلاعات حساس تاثیر میگذارد مثلا پسوردها، اطلاعات کارت اعتباری، اطلاعات مشتری و اطلاعات شخصی کاربر. بسیاری از هکهای اطلاعات محرمانه در سالهای اخیر با استفاده از انواع حملات sql injectionانجام شده است. برخی مواقع، مهاجم به سیستم های دولتی نفوذ میکند و در اصطلاح بک دور دارد در نتیجه مدتها میتواند از اطلاعات استفاده کند بدون اینکه کسی متوجه شود.
هکر با تغییر در رکوردهای دیتابیس به اهداف خود میرسد مثلا در برنامههای مالی، انتقال وجه بین حسابها انجام میدهد. با حذف رکوردیهای دیتابیس و حتی جدولهای آن، ممکن است برنامه از دسترس خارج شود تا زمانی که دیتابیس با استفاده از بکاپها ریاستور شود. حتی ممکن است با بکاپها هم کامل نتوان دیتای کامل را به دست آورد.
انواع sql injection
انواع حملات sql injection عبارتند از:
- UNION
- Error Based
- Blind
- تزریق sql کور به دو روش Boolean و Time
نقصهای برنامهنویسی، حفرههای امنیتی وب سایت و نرمافزار، امکان ترزیق کد توسط هکر را فراهم میکند. ضعف در برنامهنویسی، استفاده نادرست از متغیرهای کنترل نشده، و استفاده از دستورات نامطمئن و غیراصولی، کامپایلر را به سمت اجرای دستورات غیرمجاز سوق میدهد. به مثال زیر دقت کنید.
کوئریهای Select دارای قسمتهای زیر هستند:
- دستور Select: انتخاب ستونهای مورد نظر
- From: کدام جدول برای انتخاب ستونهای مورد نظر استفاده شود.
- Where: شروط کوئری که تزریق sql از این طریق انجام میشود.
- عبارات و پارامترهای دیگر
اگر هکر در فیلد یوزرنیم عبارت 105 OR 1=1 را وارد کند، کوئری select به شکل زیر خواهد بود:
SELECT * FROM Users WHERE UserId = 105 OR 1=1;
چون همیشه 1=1 است، تمام ردیفهای جدول Users را برمیگرداند.
اگر از دستور زیر استفاده شود هکر با یک دستور ساده، توانسته به تمام نامهای کاربری و پسوردها دست یابد:
SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;
اگر هکر در فیلد پسورد عبارت password’ OR 1=1 را وارد کند، کوئری select به شکل زیر خواهد بود:
SELECT id FROM users WHERE username='username' AND password='password' OR 1=1'
چون همیشه 1=1 است، در نتیجه اولین id از جدول Users را برمیگرداند و اصلا مهم نیست username و password چی هستند. معمولا اولین کاربر در جدول کاربران، کاربر ادمین است. بدین ترتیب هکر نه تنها به دیتابیس دسترسی یافته است بلکه امتیازات ادمین را هم دارد.
نحوه جلوگیری از حمله sql injection
برای جلوگیری از حمله sql injection و مقابله با باگ موارد زیر را در نظر بگیرید:
- اعتبارسنجی ورودی، افزایش امنیت فرمها برای جلوگیری از ورود کوئری غیرمجاز و بررسی دایمی اطلاعات ورودی قبل از ارسال آنها به دیتابیس به عنوان Query مثلا اینکه کاراکترهای غیرمجاز نداشته باشد یا ورودی مستقیم نگیرد.
- ایجاد چند کاربر با دسترسی های مختلف به دیتابیس
- توجه کنید پیغامهای خطایی که به کاربر نمایش داده میشود. مثلا “نام کاربری نمیتواند شامل اعداد باشد” هکر را آگاه میکنید که نباید در نام کاربری اعداد وارد کند. طوری این پیغامها را طراحی کنید که نقاط ضعف سایت برای هکر نمایان نشود.
- آپدیت محتوای سایت به جدیدترین نسخه
- بررسی منظم دسترسی کاربران به دیتابیس. این کار باعث میشود اگر کاربری هک شده باشد، متوجه شوید و دسترسی آن را قطع کنید.
- افزایش امنیت سایت و هاست و دیتابیس آن
- استفاده از پسوردهای قوی و پیچیده برای دیتابیس
تایید و ارزیابی ورودی کاربر
اولین کاری که باید انجام دهید این است که ورودی که توسط کاربر وارد میشود را تأیید کنید. اگر انتظار دارید ورودی یک عدد صحیح باشد، مطمئن شوید که عدد صحیح وارد شده است. اگر انتظار دریافت اعداد در قالب خاصی دریافت شوند، باید از یک مکانیزم اعتبارسنجی استفاده کنید. اکثر زبانهای برنامهنویسی قوانین اعتبارسنجی داخلی یا ماژولهای توسعهای دارند که این فرآیند را تسهیل میکند. عبارات با قاعده یکی از قدرتمندترین تکنیکها در این زمینه هستند که بهویژه در بحث ارزیابی آدرسهای ایمیلی که کاربر وارد میکند استفاده میشوند.
اگر مقداری دریافت کردید که آن چیزی نیست که انتظار آنرا دارید، آنرا رد کنید و یک پیام خطا ارسال کنید. کار هوشمندانهتر این است که ورودی را تغییر دهید و کاراکترهای مشکوک را حذف کنید، اما در این زمینه باید مهارت کافی داشته باشید.
بهطور مثال، اگر منتظر رشتهای که قرار است روی بانکاطلاعاتی متصل به وبسایتی اجرا شود، بررسی کنید که کاربر از تگهای <script> و </script> استفاده نکرده باشد، در صورت مشاهده چنین چیزی آنها را حذف کنید. اما اگر یک مهاجم چنین کاری انجام دهد چه میشود؟
<
s
<
script
>
cript
>
alert
(
'HELP'
)
</
scrip
</
script
>
t
>
وقتی رشتهای شبیه به ترکیب نحوی بالا اجرا شود و تگهای باز و بسته <script> حذف نشده باشند، رشته به دست آمده به جاوا اسکریپت درستی تبدیل میشود! بنابراین، اگر ورودی نامعتبر دریافت کردید، فقط آنرا رد کنید و یک پیام خطا ارسال کنید.
عدم اجرای مستقیم ورودیهای کاربر
بخش دوم پیشگیری این است که هرگز مستقیماً ورودی کاربر را اجرا نکنید. رایجترین روش برای حصول اطمینان از عدم اجرای اینکار، اجرای یک پرسوجوی SQL استفاده از عبارات آماده یا پرسوجوهای پارامتری شده است. برای روشن شدن بحث به ترکیب نحوی زیر دقت کنید:
SELECT * FROM orders WHERE $email=$_POST['email'] AND $id=$_POST['order_number']
به جای وارد کردن مستقیم ورودی کاربر در پرسوجو به طریقی که ترکیب نحوی بالا نشان داده شده است، میتوانید یک پرسوجو پارامتری شبیه به قطعه کد زیر ایجاد کنید:
// create mysql connection $db_connection = new mysqli('host', 'user', 'password', 'db'); // user input $email = $_POST['email']; $id = $_POST['order_number']; // create the prepared statement $ps = $db_connection->prepare("SELECT * FROM orders WHERE email = ? AND id = ?"); $ps->bind_param("si", $email, $id); $ps->execute();
این عبارت الگویی را تعریف میکند که برای پرسو جو استفاده میشود. پرسوجو قبل از اجرای دستور تعریف میشود. پارامتر si در bind_param() نشان میدهد که در انتظار یک رشته و یک عدد صحیح هستید. سپس پارامترهای ایمیل و شناسه به درستی جایگزین علامتهای سوال میشوند تا هر نوع ورودی شانس اجرا شدن را نداشته باشد.
اکنون ترکیب نحوی قبلی به صورت زیر تبدیل میشود.
SELECT * FROM orders WHERE email = 'test@example.com OR 1 = 1 -- ]' AND id = 1;
با استفاده از این تکنیک ساده قادر به پیشگیری از بروز طیف گستردهای از حملههای SQL هستید.