learn

SQL Injection چیست؟ علت، انواع و جلوگیری از تزریق SQL

توضیح تزریق SQL برای مدیر و توسعه‌دهندهٔ سایت، با تمرکز بر جداسازی داده از ساختار پرس‌وجو.

SQL Injection چیست؟ تزریق SQL زمانی رخ می‌دهد که دادهٔ غیرقابل اعتماد وارد ساختار دستور SQL شود و معنای پرس‌وجو را تغییر دهد. این آسیب‌پذیری به نحوهٔ ساخت پرس‌وجو مربوط است؛ صرف داشتن فرم یا دریافت علامت نقل‌قول از کاربر، به معنی آسیب‌پذیربودن سایت نیست.

علت اصلی SQL Injection چیست؟

فرض کنید برنامه برای یافتن یک مشتری، متن ورودی را مستقیماً به عبارت SQL اضافه کند. در این حالت مرز میان «مقدار مورد جستجو» و «دستور قابل اجرا» ممکن است از بین برود. طراحی درست، ساختار پرس‌وجو را مشخص و مقدارها را جداگانه به API پایگاه داده می‌دهد.

ورودی فقط از فرم نمی‌آید؛ URL، کوکی، دادهٔ یک سرویس یا مقدار ذخیره‌شدهٔ قبلی هم می‌تواند در ساخت SQL استفاده شود. بررسی باید مسیر کامل داده تا پرس‌وجو را پوشش دهد، نه فقط محدودکردن چند کاراکتر در مرورگر.

پیامدها به دسترسی برنامه وابسته‌اند

خواندن یا تغییر غیرمجاز داده و اختلال در عملکرد از پیامدهای ممکن‌اند. میزان آسیب به پرس‌وجوی درگیر، قابلیت‌های پایگاه داده و مجوز حساب اتصال بستگی دارد. هر SQL Injection الزاماً به کنترل سیستم‌عامل یا خواندن رمزِ متن ساده منجر نمی‌شود.

ذخیرهٔ امن رمزها و حداقل دسترسی، شدت بعضی پیامدها را کاهش می‌دهد، ولی جای رفع آسیب‌پذیری را نمی‌گیرد. همچنین دانستن نام جدول یا پیشوند آن نباید برای دسترسی به داده کافی باشد.

انواع رایج در سطح مفهومی

در روش‌های مبتنی بر خروجی، مهاجم از نتیجهٔ پاسخ یا اطلاعات خطا سرنخ می‌گیرد. در تزریق کور، تفاوت رفتار یا زمان پاسخ می‌تواند برای استنباط اطلاعات استفاده شود. «کور» به معنی بی‌اثر بودن حمله نیست.

UNION-based به استفادهٔ نامناسب از ترکیب نتایج پرس‌وجو مربوط است؛ با Prepared Statement یک مفهوم نیست. دسته‌بندی‌ها نیز فقط به دو نوع محدود نمی‌شوند. مرجع آزمون SQL Injection در OWASP تفاوت مسیرهای بررسی را شرح می‌دهد.

نمونهٔ پرس‌وجوی پارامتری در PHP

نمونهٔ زیر فرض می‌کند اتصال PDO از قبل ساخته شده و مقدار جستجو در متغیر email قرار دارد. نام جدول و ستون ثابت‌اند؛ مقدار جستجو جداگانه ارسال می‌شود.

$statement = $pdo->prepare(
    'SELECT id FROM customers WHERE email = :email'
);
$statement->execute(['email' => $email]);
$id = $statement->fetchColumn();

در مستند Prepared Statements در PHP نیز مقدار پارامتر از متن پرس‌وجو جداست. اگر ورودی را ابتدا به SQL بچسبانید و بعد prepare را صدا بزنید، از این جداسازی استفاده نکرده‌اید. مثال بالا صرفاً الگوست و اتصال، مجوز دسترسی و مدیریت خطا باید متناسب با برنامه تکمیل شود.

اعتبارسنجی و محدودیت‌های دفاع

ورودی باید با نیاز کاربرد سازگار باشد؛ مثلاً شناسهٔ عددی با محدودهٔ معتبر بررسی شود. اما اعتبارسنجی جای پارامتری‌کردن مقدارها را نمی‌گیرد. برای بخش‌های ساختاری مانند جهت مرتب‌سازی، از انتخاب‌های ثابت و مجاز برنامه استفاده کنید، نه متن آزاد کاربر.

پنهان‌کردن جزئیات خطا از خروجی عمومی جلوی افشای اطلاعات را می‌گیرد، اما علت تزریق را ترمیم نمی‌کند. WAF نیز لایهٔ کمکی است. راهنمای پیشگیری OWASP بر جداسازی داده و دستور و محدودکردن مجوزها تأکید دارد. برای سایت وردپرسی، مقالهٔ شناسایی و پیشگیری در پیوند زیر مسیر عملی بررسی را تکمیل می‌کند.

مطالعهٔ مرتبط

بازبینی فنی: ۱۳ آبان ۱۴۰۵. تاریخ انتشار اولیه و نشانی قبلی حفظ شده‌اند.

مطالب مرتبط

ارسال نظر

فهرست مطالب