MySQL و تزریق SQL — راهنمای جامع

۸۷ بازدید
آخرین به‌روزرسانی: ۲۱ شهریور ۱۴۰۲
زمان مطالعه: ۲ دقیقه
MySQL و تزریق SQL — راهنمای جامع

اگر شما ورودی کاربر را از طریق یک صفحه وب دریافت کرده و آن را در پایگاه داده MySQL درج کنید، این احتمال وجود دارد که در معرض مشکلات امنیتی گسترده‌ای به صورت تزریق SQL یا (SQL Injection) قرار بگیرید. در این مطلب از سلسله مقالات راهنمای MySQL به شما کمک می‌کنیم تا از وقوع چنین حالتی جلوگیری کرده و اسکریپت‌ها و گزاره‌های MySQL را امن‌تر بکنید.

تزریق MySQL

تزریق MySQL به طور معمول زمانی رخ می‌دهد که از کاربر چیزی مانند نام پرسیده می‌شود و او به جای نام خود یک عبارت MySQL ارائه کند که به صورت ناشناس روی پایگاه داده وب‌سایت اجرا می‌شود.

هرگز نباید به داده‌های ارائه شده از سوی کاربر اعتماد کرد و تنها پس از اعتبارسنجی باید مورد پردازش قرار گیرند. این کار از طریق تطبیق الگو صورت می‌گیرد. در مثال زیر نام کاربری محدود به کاراکترهای حرفی و ارقام به علاوه زیرخط است و طولی بین 8 و 20 کاراکتر دارد. در صورت نیاز می‌توان این قواعد را اصلاح کرد:

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM users WHERE username = $matches[0]");
} else  {
   echo "username not accepted";
}

برای نمایش مشکل، اسکریپت زیر را در نظر بگیرید:

// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

فرض شده است که این فراخوانی تابع برای بازیابی رکوردی از جدول کاربران است که ستون نام با نام ذکر شده از سوی کاربر تطبیق می‌یابد. در شرایط معمول، name$ تنها می‌تواند شامل کاراکترهای حرفی و ارقام و احتمالاً فاصله باشد. اما در این جا با الحاق یک کوئری به متغیر name$، این فراخوانی به پایگاه داده تبدیل به یک فاجعه شده است. کوئری DELETE تزریق شده موجب پاک شدن همه رکوردها از جدول users می‌شود.

خوشبختانه اگر از MySQL استفاده می‌کنید، تابع name$ امکان پشته سازی کوئری‌ها یا اجرای چندین کوئری در یک فراخوانی تابع را نمی‌دهد. اگر تلاش شود که کوئری‌ها تجمیع شوند، فراخوانی ناموفق خواهد شد.

با این وجود، افزونه‌های دیگر پایگاه داده PHP مانند SQLite و PostgreSQL، کوئری‌های پشته شده را به سادگی اجرا می‌کنند و همه کوئری‌های ارائه شده را در یک رشته اجرا کرده و مشکل جدی امنیتی ایجاد می‌کنند.

جلوگیری از تزریق SQL

شما می‌توانید همه کاراکترهای escape را به طرز هوشمندانه‌ای در زبان‌های برنامه‌نویسی مانند PERL و PHP مدیریت کنید. افزونه MySQL برای PHP تابع ()mysql_real_escape_string را برای escape کردن این کاراکترها که خاص MySQL هستند ارائه کرده است:

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}

$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

مشکل Like

برای حل مشکل Like یک مکانیسم escape کردن خاص باید کاراکترهای % و _ ارائه شده از سوی کاربر را به موارد متنی تبدیل کند. بدین منظور می‌توان از تابع ()addcslashes استفاده کرد. این تابع امکان تعیین یک بازه کاراکتری برای escape شدن را می‌دهد.

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");

اگر این نوشته برای شما مفید بوده است، آموزش‌های زیر به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
tutorialspoint
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *