sql injection چیست؟

یادداشت ویراستار: این مطلب در اسفند 1403 توسط کارشناسان سرور و شبکه فالنیک، بررسی و تایید شده است.
یکی از جدیترین انواع تهدیدات سایبری، حملات تزریق کد (Injection) هستند که به مهاجمان امکان نفوذ به سیستمهای حساس را میدهند. در این مقاله سعی داریم sql injection را بررسی کنیم و درباره نتایج این حمله، انواع و روشهای مقابله با آن صحبت کنیم. با ما همراه باشید.
فهرست محتوا
injection چیست؟
حملات injection به دستهای از حملات هک گفته میشود که در آن مهاجم، ورودی غیرقابل اعتماد وارد برنامه میکند. این ورودیها روی بخشی از دستور یا کوئری تاثیر میگذارد و اجرای آن برنامه را تغییر میدهد.
حملات injection قدیمیترین و خطرناکترین حمله به برنامههای وب است که منجر به دزدی اطلاعات، گم شدن اطلاعات، و از دست رفتن یکپارچگی اطلاعات میشود. بیشتر آسیبهای اینجکشن، تایید اعتبار ورودی نامناسب کاربر است. در بسیاری از موارد، اطلاعات بهدستآمده از طریق حملات SQL 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
برخی از حملات SQL Injection میتوانند در ترکیب با حملات مرد میانی (MITM) اجرا شوند تا اطلاعات حساس کاربران رهگیری شود. [بیشتر بخوانید: حمله مرد میانی چیست] همچنین در حملات پیشرفته، مهاجمان ممکن است از تکنیک Evil Twin در کنار SQL Injection برای سرقت اطلاعات ورود کاربران استفاده کنند. [بیشتر بخوانید: حمله evil twin چیست]
انواع حملات 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، استفاده از روشهای امنیتی در طراحی وبسایتها ضروری است. [بیشتر بخوانید: جلوگیری از هک وب سایت ها] علاوه بر وبسایتها، اطلاعات سرقتشده از طریق SQL Injection ممکن است برای نفوذ به حسابهای شبکههای اجتماعی و دستگاههای کاربران استفاده شود. [بیشتر بخوانید: جلوگیری از هک شدن گوشی] همچنین هکرها ممکن است پس از حمله SQL Injection، یک روتکیت را روی سرور نصب کنند تا به صورت مخفیانه کنترل آن را در دست بگیرند. [بیشتر بخوانید: rootkit چیست]
دقت داشته باشید که اگر اطلاعات کاربران از طریق 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 هستید.
حملات مرتبط با sql injection
SQL Injection نه تنها یک تهدید برای دسترسی به دادههای حساس در پایگاه دادههاست، بلکه میتواند منجر به حملات پیچیدهتری شود. مهاجمان پس از دستیابی به اطلاعات کاربران از طریق SQL Injection، ممکن است از این دادهها برای دسترسی به حسابهای آنلاین و سرقت اطلاعات شخصی استفاده کنند. این حملات میتوانند در ترکیب با تهدیدات دیگر، مانند حمله مرد میانی یا اسپوفینگ، به افزایش خطرات امنیتی دامن بزنند. علاوه بر این، اطلاعات سرقتشده ممکن است به فیشینگ و rootkit ها منجر شوند که به هکرها اجازه میدهند به طور مخفیانه سیستمها را کنترل کنند. در برخی موارد، حملات SQL Injection به بخشی از حملات دیداس یا botnet ها تبدیل میشود که هدف اصلی آنها ایجاد اختلال و آسیب به زیرساختهای شبکه است.
بررسی تزریق SQL همراه با مثال
همانطور که اشاره کردیم، حمله تزریق کد اسکیوال (SQL injection) یکی از رایجترین حملات سایبری است. همه این حملات از یک عامل سرچشمه میگیرند: عدم مدیریت صحیح دادههای ارسال شده توسط کاربر. بیایید به چند نمونه از حملات تزریقی نگاهی داشته باشیم.
استفاده از تابع eval() برای تزریق SQL
برای اینکه ببینید چقدر آسان است که از یک برنامه آسیبپذیر با تزریق کد سمت سرور بهرهبرداری کنید، باید نگاهی به تابع eval() زبان برنامهنویسی پیاچپی داشته باشیم.
تابع eval() یک رشته را به عنوان یک کد زبان برنامهنویسی پیاچپی ارزیابی میکند. این تابع میتواند ورودی ارسال شده توسط کاربر را دریافت کرده و آنرا به عنوان کد اجرا کند. این حالت کاملا خطرناک است، به خصوص اگر اقدامات احتیاطی مناسب انجام نشود. اجازه دهید برای درک خطرناک بودن این تابع عملکرد یک برنامه ماشین حساب فرضی را بررسی کنیم. ماشین حساب ساده زیر به کاربر اجازه میدهد معادلهای را وارد کنید و سپس نتیجه را مشاهده کنید.
$userExpression = '5+3'; echo eval('return ' . $userExpression . ';');
عالی! کاربر ورودی خود را ارسال کرد، ماشین حساب از تابع eval() برای حل معادله استفاده کرد و سپس مقدار صحیح که برابر با 8 است را بازگرداند. اما چه اتفاقی میافتد وقتی یک کاربر ورودی را بدهد که قرار است کار دیگری را انجام دهد.
$userExpression = 'phpInfo();5+3'; echo eval('return ' . $userExpression . ';');
از آنجایی که هیچ مکانیزم اعتبار ورودی وجود ندارد، کاربر میتواند هر چیزی را که میخواهد تایپ کند و به عنوان کد PHP ارزیابی شده و اجرا شود. اگر مهاجم بتواند هر کدی که مایل است را اجرا کند، میتواند برنامه شما را خراب کند یا میتواند اقدام به واکشی اطلاعات مختلف از بانکهای اطلاعاتی کرده یا دستورات مخرب را روی بانکهای اطلاعاتی مورد استفاده برنامه اجرا کند.
عدم حفاظت و ارزیابی درخواستهای SQL توسط توسعهدهندگان
برای اجرای یک حمله SQLi، کاربر یک پرسوجوی SQL را به ورودی که به برنامه ارسال میکند اضافه میکند. اگر برنامه هیچ مکانیزم حفاظتی و ارزیابی در نظر نگرفته باشد، پرسوجوی ارسال شده توسط کاربر مستقیما روی بانک اطلاعاتی اجرا میشود که میتواند باعث تخریب گسترده پایگاه داده برنامه شود.
یک مثال رایج از حمله این است که شخصی با اجرای یک حمله بر روی فرم ورودی به اطلاعات کاربری دسترسی پیدا میکند. این موضوع ویرانگر خواهد بود، اما اگر مهاجم برخی از دادههایی را که ممکن است به نظر حساس نمیرسند را هدف قرار دهد، چه اتفاقی میافتد؟ شاید زمانی که توسعهدهنده فرم را ایجاد میکند، به ذهنشان خطور نمیکند که محافظت بیشتری به آن اضافه کند، زیرا این فرم دارای اطلاعات حساس کاربری نیست. این موضوع هم خطرناک است. برای روشن شدن بحث به مثال زیر دقت کنید:
تصور کنید وبسایتی دارید که به کاربران امکان میدهد با وارد کردن شماره سفارش و آدرس ایمیل خود در یک فرم، اطلاعات سفارش خود را بررسی کنند.

پرسوجو برای دریافت اطلاعات سفارش بر اساس ورودیهای فرم چیزی شبیه به حالت زیر است:
SELECT * FROM orders WHERE $email=$_POST['email'] AND $id=$_POST['order_number'];
کاربر شماره سفارش و ایمیل خود را وارد میکند و سپس پرسوجو با آن ورودیها اجرا میشود تا دادهها را از پایگاه داده واکشی کند.

اکنون هکری این فرم را مشاهده میکند و تصمیم میگیرد دستوراتی را اجرا کند. در این حالت به جای اینکه ایمیل خود را تایپ کند، این مقادیر را به عنوان ورودی وارد میکند:
Email: test@example.com' OR 1 = 1 -- '] Order Number: 1

اکنون برنامه شما آن ورودی را میگیرد و آن را مستقیماً در رشته SQL قرار میدهد. چیزی که اجرا میشود به دستور فوق تبدیل میشود:
SELECT * FROM orders WHERE email='test@example.com' OR 1 = 1 -- '] AND id=1;
و نتیجه؟ مهاجم اکنون اطلاعات سفارش همه را دارد که میتواند به معنای نامها، ایمیلها، آدرسها و موارد دیگر باشد.
دقیقا چه اتفاقی افتاد؟ از آنجایی که کاربر نهایی هر آن چیزی که در جعبه ورودی تایپ میکند بهعنوان کد SQL اجرا میشود، این توانایی را دارد تا یک شرطی اضافی را به پرس و جو متصل کند (1 = 1) تا فرآیند ارزیابی همیشه درست میشود. ادامه پرسوجو حاوی یک عملگر AND است، اما مهاجم با درج کدی، آنرا بهعنوان یک نظر (کدی که اجرا نمیشود) تبدیل کرده است. حتی اگر کد بخش AND را به حالت نقطه نظر تبدیل نمیکرد، باز هم میتوانست هر شماره سفارشی را ارسال کند و دادههای آنرا دریافت کنند، حتی اگر ایمیل درستی در اختیار نداشته باشد.
در سال 2018 میلادی شرکت لنوو مشابه چنین حملهای را تجربه کرد که باعث بروز نقض دادهای شد که اطلاعات یک میلیون مشترک این شرکت را فاش کرد. بهطوری که هکرها توانستند از طریق پیادهسازی حمله تزریق کد اسکیوال دسترسی کامل به وبسایت این شرکت به دست آورند.
در آن حمله، هکرها توانستند یک شناسه محصول را به صورت آنلاین پیدا کنند که به طور تصادفی آنها را به صفحه خطا هدایت کرد. سپس با استفاده از این صفحه خطا، هکرها اقدام به وارد کردن یک سری رشتههای پرسوجو کردند و در نهایت دسترسی کامل در سطح مدیر به وبسایت و تمام محتویات آن بهدست آورند. در آن حمله هکرها به بیش از 20 گیگابایت داده دسترسی پیدا کردند.
تزریق SQL فقط به سرقت از پایگاه داده محدود نمیشود. نگرانی دیگری که وجود دارد یکپارچگی دادهها است. اگر یک مهاجم به پایگاه داده دسترسی داشته باشد، میتواند با تغییر دادههای موجود در آن آسیب زیادی به اطلاعات وارد کند، پرسشی که مطرح است این است که یک مهاجم از تغییر دادهها چه چیزی به دست آورد؟ در اینجا دو سناریو مفروض است:
1. یک مهاجم به پایگاه داده مراقبتهای بهداشتی که حاوی اطلاعات حساس کاربران است دسترسی پیدا میکند. در اینجا هکر میتواند اطلاعات روی پایگاه داده اصلی را تغییر دهد. در اینجا سازمان مربوطه ممکن است تا مدتها متوجه این تغییرات نشود و زمانی که نشانههای آشکاری را مشاهده کرد تازه متوجه شوند که چه اتفاقاتی افتاده که دیگر خیلی دیر است. در این مدت مهاجم ممکن است از شرکت برای بازگرداندن تغییرات به حالت اصلی باجخواهی کند یا اسناد را بهگونهای تغییر دهد تا از شرکتهای بیمه پول دریافت کند.
2. در سناریو دوم، یک مهاجم به سراغ پایگاه داده یک صرافی رمزنگاری محبوب میرود که اطلاعات لحظهای مربوط به تغییر قیمتها و خرید و فروش ارزها را از طریق وبسایت انجام میدهند. دستکاری اطلاعات پایگاههای دادهای میتواند منجر به خرید یا فروش انبوه سهام شود که در نهایت بسته به اهداف مهاجم ممکن است پول زیادی عاید او کند یا سهام یک شرکت را به مرز سقوط و ورشکستگی ببرد.
همانگونه که مشاهده میکنید، حفرهها در برنامههای کاربردی و پایگاههای دادهای میتوانند باعث بروز مشکل نقضهای دادهای به روشهای مختلف شوند.