آموزش رایگان PHP

آموزش Prepared Statement در PHP: امن‌سازی دیتابیس در برابر SQL Injection

1405/05/13 21:17 محراب حسن زاده
آموزش Prepared Statement در PHP: امن‌سازی دیتابیس در برابر SQL Injection

حمله SQL Injection چیست و چرا دیتابیس ما را تهدید می‌کند؟

یکی از رایج‌ترین و خطرناک‌ترین آسیب‌پذیری‌های امنیتی در وب، حمله تزریق دیتابیس یا SQL Injection (SQLi) است. این حمله زمانی رخ می‌دهد که ورودی کاربر مستقیماً و بدون فیلترسازی در ساختار کوئری‌های SQL قرار گیرد. در این حالت، نفوذگر با وارد کردن دستورات مخرب SQL می‌تواند منطق کوئری شما را تغییر داده، به اطلاعات حساس (مانند رمزهای عبور) دسترسی پیدا کرده و یا حتی کل دیتابیس را حذف کند.

گوگل و نهادهای امنیتی معتبری مانند OWASP، استفاده از عبارات آماده یا Prepared Statements را به عنوان مطمئن‌ترین و استانداردترین راهکار برای مقابله با این آسیب‌پذیری معرفی کرده‌اند.

Prepared Statement چیست و چگونه کار می‌کند؟

در روش‌های سنتی، ساختار کوئری و داده‌های ورودی با هم ترکیب شده و یکجا به دیتابیس ارسال می‌شوند. اما در Prepared Statement، این فرآیند به دو مرحله مجزا تقسیم می‌شود:

  1. مرحله آماده‌سازی (Prepare): قالب کوئری SQL (بدون داده‌های واقعی کاربر) به دیتابیس فرستاده می‌شود. دیتابیس ساختار کوئری را آنالیز و بهینه‌سازی می‌کند.
  2. مرحله ارسال داده و اجرا (Execute): داده‌های کاربر به عنوان پارامترهای مجزا به سمت دیتابیس ارسال شده و به قالب متصل می‌شوند. در این حالت، دیتابیس به داده‌ها صرفاً به عنوان یک «مقدار متنی خام» نگاه می‌کند و هیچ دستور SQLی را درون ورودی کاربر اجرا نخواهد کرد.

آموزش استفاده از Prepared Statement با استفاده از PDO (توصیه شده)

کتابخانه PDO (PHP Data Objects) بهترین و استانداردترین روش برای اتصال به دیتابیس در PHP است چرا که از دیتابیس‌های مختلف پشتیبانی می‌کند و امنیت بالایی دارد.

در ادامه یک نمونه کد کامل برای اجرای کوئری امن با PDO آورده شده است:


try {
    // 1. اتصال امن به دیتابیس به وسیله PDO
    $dsn = "mysql:host=localhost;dbname=my_secure_db;charset=utf8mb4";
    $username = "root";
    $password = "";
    $options = [
        PDO::ATTR_ERRMODE            =--> PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false, // خاموش کردن شبیه سازی برای امنیت واقعی
    ];
    
    $pdo = new PDO($dsn, $username, $password, $options);

    // ۲. تعریف کوئری با استفاده از Placeholders (:username)
    $sql = "SELECT id, email, password FROM users WHERE username = :username_param LIMIT 1";
    
    // ۳. آماده سازی کوئری در دیتابیس
    $stmt = $pdo->prepare($sql);
    
    // ۴. بایند کردن داده کاربر به صورت کاملا امن
    $userInput = "admin' OR '1'='1"; // یک ورودی مخرب نمونه
    $stmt->bindParam(':username_param', $userInput, PDO::PARAM_STR);
    
    // ۵. اجرا
    $stmt->execute();
    
    $user = $stmt->fetch();
    
    if ($user) {
        echo "کاربر با موفقیت یافت شد!";
    } else {
        echo "کاربری یافت نشد.";
    }
    
} catch (PDOException $e) {
    // در محیط پروڈکشن هرگز جزییات خطا را به کاربر نمایش ندهید
    error_log($e->getMessage());
    die("خطایی در سیستم رخ داده است.");
}

آموزش استفاده از Prepared Statement در MySQLi

اگر پروژه شما از اکستنشن قدیمی‌تر MySQLi استفاده می‌کند، باز هم باید از عبارات آماده به شکل زیر بهره ببرید:



// ۱. ایجاد اتصال به دیتابیس
$mysqli = new mysqli("localhost", "root", "", "my_secure_db");

if ($mysqli--->connect_error) {
    die("اتصال ناموفق: " . $mysqli->connect_error);
}

// ۲. کوئری با استفاده از علامت سوال ?
$sql = "SELECT id, email FROM users WHERE email = ?";

// ۳. آماده سازی در دیتابیس
$stmt = $mysqli->prepare($sql);

if ($stmt) {
    $emailInput = "test@example.com";
    
    // ۴. بایند کردن پارامتر (s مخفف string است)
    $stmt->bind_param("s", $emailInput);
    
    // ۵. اجرا
    $stmt->execute();
    
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        echo "شناسه کاربر: " . $row['id'];
    }
    
    $stmt->close();
}
$mysqli->close();

تفاوت اجرای امن و غیر‌امن در دیتابیس

هنگامی که از Prepared Statement استفاده می‌کنید، موتور دیتابیس کوئری را کامپایل کرده و جایگاه داده‌ها را مشخص می‌کند. اگر کاربر متنی مانند admin' OR '1'='1 وارد کند، دیتابیس فیلد نام کاربری را دقیقا برابر با کل این متن جستجو می‌کند و هرگز بخش OR '1'='1 را به عنوان دستور شرطی منطقی اجرا نخواهد کرد.

این تفاوت بنیادین، راه نفوذ و دور زدن اهراز هویت در دیتابیس را برای همیشه مسدود خواهد کرد.


پیشنمایش

پرسش و پاسخ

نظری یافت نشد

مطالب مشابه

آموزش جامع تعریف تابع سفارشی در PHP طبق استاندارد گوگل و PSR
1405/04/16 01:07

آموزش جامع تعریف تابع سفارشی در PHP طبق استاندارد گوگل و PSR

مطالعه بیشتر
راهنمای جامع پاک‌سازی داده‌های ورودی در PHP بر اساس استانداردهای گوگل
1405/04/27 22:21

راهنمای جامع پاک‌سازی داده‌های ورودی در PHP بر اساس استانداردهای گوگل

مطالعه بیشتر
آموزش کامل ویژگی background در CSS: تنظیمات پس‌زمینه برای طراحی وب راهنمای جامع
1402/06/05 23:51

آموزش کامل ویژگی background در CSS: تنظیمات پس‌زمینه برای طراحی وب راهنمای جامع

مطالعه بیشتر
آشنایی با Emit در Vue.js | انتقال رویدادها از کامپوننت فرزند به والد
1404/09/24 20:52

آشنایی با Emit در Vue.js | انتقال رویدادها از کامپوننت فرزند به والد

مطالعه بیشتر
آموزش فیلتر کردن داده‌ها در PHP با توابع filter_var و preg_match
1405/05/13 21:29

آموزش فیلتر کردن داده‌ها در PHP با توابع filter_var و preg_match

مطالعه بیشتر
آموزش کامل ساخت و افزودن تقویم فارسی به Input (کامل و استاندارد)
1405/03/14 00:07

آموزش کامل ساخت و افزودن تقویم فارسی به Input (کامل و استاندارد)

مطالعه بیشتر
آموزش کامل عملگرهای منطقی در PHP (همراه با تفاوت‌های کلیدی)
1405/04/03 23:56

آموزش کامل عملگرهای منطقی در PHP (همراه با تفاوت‌های کلیدی)

مطالعه بیشتر
درک و استفاده از Watchers در Vue.js | آموزش Watch با مثال کاربردی
1404/09/28 22:00

درک و استفاده از Watchers در Vue.js | آموزش Watch با مثال کاربردی

مطالعه بیشتر
آشنایی با Inheritance در CSS: اصول وراثت و مدیریت استایل‌ها
1403/08/12 19:59

آشنایی با Inheritance در CSS: اصول وراثت و مدیریت استایل‌ها

مطالعه بیشتر
مفاهیم پیشرفته در کلاس‌ها و وراثت (Super, Extends) در جاوا اسکریپت: راهنمای کامل و مثال‌ها
1403/07/29 20:25

مفاهیم پیشرفته در کلاس‌ها و وراثت (Super, Extends) در جاوا اسکریپت: راهنمای کامل و مثال‌ها

مطالعه بیشتر
آموزش سیر تا پیاز تاریخ و زمان در PHP (استاندارد گوگل)
1405/04/27 21:58

آموزش سیر تا پیاز تاریخ و زمان در PHP (استاندارد گوگل)

مطالعه بیشتر
کار با فیلترهای CSS: آموزش استفاده از blur، brightness و contrast برای افکت‌های تصویری جذاب
1403/08/11 21:08

کار با فیلترهای CSS: آموزش استفاده از blur، brightness و contrast برای افکت‌های تصویری جذاب

مطالعه بیشتر

تمامی حقوق معتلق به ناشر سایت است و کپی از آن پیگرد قانونی دارد