
SQL Injection چیست؟ انواع حمله تزریق SQL و روشهای جلوگیری
یک فروشگاه اینترنتی برای نمایش محصولات، ورود کاربران و ثبت سفارش با پایگاه داده ارتباط دارد. اگر برنامه ورودی کاربران را بدون جداسازی از دستورهای SQL وارد پرسوجو کند، مهاجم ممکن است منطق درخواست را تغییر دهد. این آسیبپذیری را SQL Injection یا تزریق SQL مینامند. برای درک اینکه SQL Injection چیست، باید تفاوت «داده […]
SQL Injection چیست؟ انواع حمله تزریق SQL و روشهای جلوگیری
یک فروشگاه اینترنتی برای نمایش محصولات، ورود کاربران و ثبت سفارش با پایگاه داده ارتباط دارد. اگر برنامه ورودی کاربران را بدون جداسازی از دستورهای SQL وارد پرسوجو کند، مهاجم ممکن است منطق درخواست را تغییر دهد. این آسیبپذیری را SQL Injection یا تزریق SQL مینامند.
برای درک اینکه SQL Injection چیست، باید تفاوت «داده ورودی» و «دستور اجرایی» را بشناسیم. کاربر باید فقط مقدار مورد نیاز برنامه را ارسال کند؛ مثلا نام محصول یا شماره سفارش. مشکل زمانی شروع میشود که برنامه بخشی از این ورودی را بهعنوان دستور دیتابیس تفسیر کند. در این مقاله از پارس هاست، سازوکار حمله، انواع آن و روشهای پیشگیری را بررسی میکنیم.
SQL Injection یا تزریق SQL چیست؟
SQL Injection نوعی آسیبپذیری امنیتی است که به مهاجم اجازه میدهد روی پرسوجوهای ارسالی برنامه به پایگاه داده اثر بگذارد. SQL زبان ارتباط با دیتابیسهای رابطهای است و برنامهها برای خواندن، ثبت، ویرایش یا حذف اطلاعات از آن استفاده میکنند.
اگر برنامه متن ورودی کاربر را مستقیم به متن کوئری بچسباند، ممکن است مرز میان داده و دستور از بین برود. در نتیجه، دیتابیس بهجای اجرای درخواست موردنظر توسعهدهنده، پرسوجویی با منطق متفاوت اجرا میکند.
SQLi نام کوتاه همین آسیبپذیری است. این مشکل به زبان برنامهنویسی خاصی محدود نیست؛ شیوه ساخت و اجرای کوئری اهمیت دارد. داشتن فرم ورود یا استفاده از دیتابیس SQL هم بهتنهایی نشانه آسیبپذیری نیست.
حمله SQL Injection چگونه انجام میشود؟
در یک برنامه آسیبپذیر، ورودی از مرورگر یا کلاینت دریافت میشود، وارد متن پرسوجو میشود و سپس به دیتابیس میرسد. مهاجم تلاش میکند ورودی را طوری تنظیم کند که ساختار یا شرطهای پرسوجو تغییر کنند.
نقطه ورود فقط کادرهای قابلمشاهده نیست. پارامتر آدرس، بدنه درخواست API، کوکی یا هدر هم ممکن است در ساخت کوئری نقش داشته باشد. حتی دادهای که برنامه قبلا ذخیره کرده، هنگام استفاده دوباره در یک کوئری ناامن خطرساز است.
نتیجه حمله به محل آسیبپذیری، نوع دیتابیس و دسترسی حساب برنامه بستگی دارد. هر تزریق SQL لزوما به کنترل کامل سرور منتهی نمیشود.
مثال ساده از حمله SQL Injection
فرض کنید فروشگاهی نام دستهبندی را از آدرس صفحه دریافت میکند. برنامه باید فقط محصولات همان دسته را نمایش دهد؛ مثلا «لوازم جانبی».
در نسخه آسیبپذیر، توسعهدهنده مقدار دستهبندی را مستقیم داخل متن پرسوجو قرار میدهد. یک ورودی دستکاریشده ممکن است شرط انتخاب محصولات را تغییر دهد و کالاهایی را نمایش دهد که نباید در نتیجه حضور داشته باشند.
در نسخه امن، متن کوئری ساختار مشخصی دارد و مقدار دستهبندی جداگانه به آن متصل میشود. دیتابیس این مقدار را داده در نظر میگیرد، حتی اگر ظاهر آن شبیه دستور SQL باشد.
انواع حملات SQL Injection
یکی از دستهبندیهای رایج، روش دریافت نتیجه حمله است. بر این اساس، تزریق SQL را به سه گروه درونباند، کور و خارج از باند تقسیم میکنند.
١. تزریق SQL درونباند (In-band SQLi)
در این روش، مهاجم نتیجه را از همان مسیر ارتباطی دریافت میکند که درخواست را فرستاده است؛ مثلا پاسخ صفحه وب.
دو شکل شناختهشده آن عبارتاند از:
- مبتنی بر خطا: پیام خطای دیتابیس اطلاعاتی درباره ساختار پرسوجو یا دادهها آشکار میکند.
- مبتنی بر UNION: مهاجم تلاش میکند نتیجه یک پرسوجوی دیگر را با خروجی درخواست اصلی ترکیب کند.
نمایش جزئیات خطا به بازدیدکننده، بررسی حمله را آسانتر میکند؛ اما پنهانکردن خطا بهتنهایی آسیبپذیری را رفع نمیکند.

٢. تزریق SQL کور (Blind SQLi)
در تزریق کور، برنامه نتیجه دیتابیس را مستقیم نشان نمیدهد. مهاجم از تفاوت رفتار برنامه برای استنباط اطلاعات استفاده میکند.
در روش مبتنی بر شرط، تفاوت پاسخ به درست یا نادرستبودن یک شرط وابسته است. در روش مبتنی بر زمان، تغییر مدت پاسخ سرنخی برای بررسی فراهم میکند.
البته کندی سایت یا تفاوت محتوای دو پاسخ، بهتنهایی اثبات تزریق SQL نیست؛ کش، بار سرور و منطق برنامه هم روی پاسخ اثر دارند.
٣. تزریق SQL خارج از باند (Out-of-band SQLi)
در این روش، دریافت نتیجه از کانالی جدا از پاسخ عادی برنامه انجام میگیرد؛ مثلا از طریق ارتباط شبکهای که دیتابیس آغاز میکند.
امکان این حمله به قابلیتهای دیتابیس، سطح دسترسی و محدودیت ارتباطهای خروجی بستگی دارد. بنابراین همه محیطها شرایط اجرای آن را ندارند.
| نوع حمله | مسیر دریافت اطلاعات | نکته مهم |
| درونباند | پاسخ مستقیم برنامه | خروجی یا خطا ممکن است اطلاعات آشکار کند |
| کور | تفاوت محتوا یا زمان پاسخ | نتیجه مستقیم نمایش ندارد |
| خارج از باند | کانال ارتباطی جداگانه | به امکانات و دسترسی شبکه وابسته است |
حمله SQL Injection چه خطراتی دارد؟
خطر اصلی، دسترسی غیرمجاز به اطلاعات و تغییر رفتار برنامه است. برای یک فروشگاه، افشای نشانی مشتریان یا تغییر اطلاعات سفارش، فقط مشکل فنی نیست؛ اعتماد مشتری و ادامه فعالیت کسبوکار هم آسیب میبیند.
پیامدهای احتمالی شامل این موارد است:
- افشای اطلاعات کاربران و سوابق خرید
- تغییر یا حذف رکوردهای دیتابیس
- دورزدن منطق ورود در برخی پیادهسازیهای آسیبپذیر
- دستکاری وضعیت سفارش یا سطح دسترسی
- اختلال در سرویس و افزایش هزینه بازیابی
شدت خسارت به اختیارات حساب دیتابیس هم وابسته است. حسابی که فقط اجازه خواندن چند جدول دارد، با حساب مدیریتی یکسان نیست.

نگهداری نسخه پشتیبان دیتابیس برای بازیابی اهمیت دارد، اما بکاپ جلوی افشای اطلاعات را نمیگیرد. نسخهها را جدا از محیط اصلی نگه دارید و بازیابی را دورهای امتحان کنید.
کدام بخشهای سایت در برابر SQL Injection آسیبپذیرند؟
هر بخشی که داده ورودی را به کوئری تبدیل میکند، نیاز به بررسی دارد. محدودکردن ارزیابی به صفحه ورود، بخش بزرگی از مسیرهای احتمالی را نادیده میگذارد.
نقاط مهم عبارتاند از:
- فرم ورود، ثبتنام و بازیابی حساب
- جستجو و فیلتر محصولات
- مرتبسازی جدولها و گزارشها
- پارامترهای شناسه محصول، سفارش یا کاربر
- APIهای وب و اپلیکیشن
- پنل مدیریت و ابزارهای گزارشگیری
پنل داخلی هم صرفا بهدلیل نیاز به ورود امن نیست. همچنین داده ذخیرهشده را نباید خودکار قابلاعتماد دانست؛ ممکن است برنامه بعدا همان مقدار را داخل یک کوئری ناامن استفاده کند.
چگونه از حملات SQL Injection جلوگیری کنیم؟
پیشگیری از محل ساخت کوئری آغاز میشود. کنترل ورودی، محدودسازی دسترسی و تجهیزات امنیتی باید این دفاع را تکمیل کنند. در ادامه نحوه جلوگیری از حملات SQL Injection را معرفی میکنیم:
١. استفاده از کوئریهای پارامتری (Prepared Statements)
در کوئری پارامتری، ساختار دستور و مقدارهای ورودی، جداگانه به درایور دیتابیس میرسند. توسعهدهنده ابتدا جای مقدارها را مشخص میکند و سپس داده را از مسیر پارامترها متصل میکند.
صرف استفاده از نام Prepared Statement کافی نیست؛ اگر برنامه پیش از آمادهسازی، ورودی را به متن SQL بچسباند، مشکل باقی میماند. استفاده از ORM هم کوئری خام و ناامن را خودکار اصلاح نمیکند.
طبق راهنمای OWASP، کوئری پارامتری از دفاعهای اصلی است. برای نام جدول، ستون یا جهت مرتبسازی که معمولا جای پارامتر مقداری نیستند، گزینههای مجاز را در کد مشخص کنید.
٢. اعتبارسنجی ورودی کاربران و محدودسازی دسترسی دیتابیس
اعتبارسنجی را سمت سرور انجام دهید. اگر شناسه سفارش باید عدد مثبت باشد، مقدارهای ناسازگار را رد کنید. برای گزینههای محدود، مثل شیوه مرتبسازی، فهرست مجاز داشته باشید.
حذف چند کاراکتر یا مسدودکردن چند کلمه، جای کوئری پارامتری را نمیگیرد. نام واقعی کاربران هم ممکن است علامتهایی داشته باشد که فیلترهای ساده اشتباها حذف میکنند.
برای حساب دیتابیس برنامه فقط دسترسی لازم را تعریف کنید. سرویس گزارشگیری که صرفا اطلاعات میخواند، معمولا نیازی به حذف جدول ندارد. حساب مدیریتی را هم برای اتصال روزمره برنامه انتخاب نکنید.

٣. استفاده از فایروال برنامه وب (WAF)
فایروال WAF درخواستهای وب را با قواعد امنیتی بررسی میکند و ممکن است برخی تلاشهای تزریق SQL را متوقف کند. این ابزار برای کاهش ریسک و کنترل موقت مسیر آسیبپذیر مفید است، اما اصلاح کد همچنان ضرورت دارد.

اگر از سرویس CDN استفاده میکنید، قابلیت WAF و شرایط فعالسازی آن را جداگانه بررسی کنید؛ هر CDN چنین قابلیتی ندارد. برای جلوگیری از عبور درخواستها از مسیر محافظتنشده، دسترسی مستقیم به سرور مبدا را هم ارزیابی کنید.
۴. بهروزرسانی و مدیریت خطاها
هسته سایت، افزونهها، چارچوب برنامه و درایور دیتابیس را بهروز نگه دارید. در سایتهای آماده، یک افزونه قدیمی ممکن است مسیر آسیبپذیر را ایجاد کند.

جزئیات خطای SQL، نام جدول و مسیر فایل را به بازدیدکننده نشان ندهید. این اطلاعات را در لاگ با دسترسی محدود ثبت کنید تا تیم فنی امکان بررسی داشته باشد.
روشهای شناسایی و تست آسیبپذیری SQL Injection
بررسی معتبر، ترکیبی از بازبینی کد و آزمون رفتار برنامه است. تست را روی سامانه متعلق به خودتان یا در محدوده مجوز مشخص انجام دهید؛ محیط آزمایشی با داده غیرواقعی برای شروع مناسبتر است.
روند بررسی شامل این مراحل است:
- شناسایی ورودیها: مسیرهای دریافت داده، از فرمها تا APIها، فهرست شوند.
- بازبینی کوئریها: اتصال مستقیم متن ورودی به SQL بررسی شود.
- آزمون کنترلشده: تفاوت پاسخها همراه با لاگ برنامه و دیتابیس تحلیل شود.
- تایید یافته: نتیجه اسکنر پیش از اعلام آسیبپذیری بررسی شود.
- اصلاح و آزمون دوباره: مسیر معیوب و عملکرد عادی برنامه دوباره ارزیابی شوند.

ابزارهای SAST کد را بررسی میکنند و ابزارهای DAST رفتار برنامه در حال اجرا را میسنجند. هیچکدام بهتنهایی نبود آسیبپذیری را ثابت نمیکنند. OWASP هم بر ترکیب ابزارهای خودکار با بررسی دستی و شناخت منطق برنامه تاکید دارد.
پس از رفع مشکل، یک آزمون بازگشتی برای همان مسیر تعریف کنید تا تغییرات بعدی، ساخت ناامن کوئری را دوباره وارد برنامه نکنند.
تفاوت SQL Injection و XSS چیست؟
در SQL Injection، مشکل به تفسیر ناامن ورودی در پرسوجوی دیتابیس مربوط است. در XSS، برنامه محتوای غیرقابلاعتماد را به شکلی وارد صفحه میکند که مرورگر آن را کد فعال تفسیر میکند.
| معیار | SQL Injection | XSS |
| محل اثر اصلی | کوئری دیتابیس | محتوای صفحه در مرورگر |
| پیامد رایج | خواندن یا تغییر غیرمجاز داده | اجرای اسکریپت در بستر سایت |
| دفاع اصلی | پارامتریکردن کوئری | کدگذاری متناسب با محل خروجی |
| کنترل تکمیلی | محدودسازی دسترسی دیتابیس | پاکسازی HTML در صورت نیاز |
در نتیجه، راهکار این دو یکسان نیست. کوئری پارامتری جلوی حمله XSS را نمیگیرد و کدگذاری HTML هم جای دفاع در برابر تزریق SQL را ندارد.
امنیت دیتابیس از کد برنامه شروع میشود
برای کاهش ریسک تزریق SQL، ابتدا مسیر ساخت کوئریها را بررسی کنید. سپس دسترسی حساب دیتابیس، بهروزرسانی وابستگیها، ثبت خطا و قواعد WAF را کنار هم قرار دهید.
برای مدیر سایت، اقدام عملی این است که از تیم فنی بخواهید استفاده از کوئری پارامتری را بررسی کند، نقاط ورودی مهم را آزمایش کند و نتیجه اصلاحها را مستند کند.
سوالات متداول درباره SQL Injection
۱. آیا SQL Injection فقط در سایتهای PHP رخ میدهد؟
خیر. هر برنامهای که ورودی غیرقابلاعتماد را ناامن وارد دستور SQL کند، ممکن است آسیبپذیر باشد. زبان برنامهنویسی بهتنهایی تعیینکننده نیست.
۲. آیا نصب WAF برای جلوگیری از SQL Injection کافی است؟
خیر. WAF یک لایه کمکی است. رفع ریشه آسیبپذیری به اصلاح ساخت کوئری و استفاده درست از پارامترها نیاز دارد.
۳. آیا SSL جلوی تزریق SQL را میگیرد؟
خیر. SSL/TLS ارتباط را رمزنگاری میکند؛ اما ورودی مخرب هم ممکن است از همین ارتباط رمزنگاریشده به برنامه برسد.
۴. آیا استفاده از ORM امنیت کامل ایجاد میکند؟
خیر. قابلیتهای امن ORM مفیدند، اما کوئری خام یا اتصال مستقیم ورودی به متن دستور همچنان خطر دارد.
۵. آیا بکاپ دیتابیس آسیب تزریق SQL را جبران میکند؟
بکاپ سالم به بازیابی اطلاعات کمک میکند، اما اطلاعات افشاشده را پس نمیگیرد. پیش از بازگرداندن سرویس، مسیر آسیبپذیر را هم اصلاح کنید.
۰