آموزش رایگان 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 را به عنوان دستور شرطی منطقی اجرا نخواهد کرد.

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


پیشنمایش

پرسش و پاسخ

نظری یافت نشد

مطالب مشابه

راهنمای کامل تگ‌های < img > و < a > در HTML: تصاویر و لینک‌ها
1402/05/21 00:27

راهنمای کامل تگ‌های < img > و < a > در HTML: تصاویر و لینک‌ها

مطالعه بیشتر
مفهوم متغیرها و انواع داده در جاوا اسکریپت: راهنمای جامع برای مبتدیان
1402/06/28 00:07

مفهوم متغیرها و انواع داده در جاوا اسکریپت: راهنمای جامع برای مبتدیان

مطالعه بیشتر
آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده
1405/05/01 20:01

آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده

مطالعه بیشتر
معرفی جاوا اسکریپت و نحوه استفاده از آن برای توسعه وب تعاملی: راهنمای جامع
1402/06/27 23:35

معرفی جاوا اسکریپت و نحوه استفاده از آن برای توسعه وب تعاملی: راهنمای جامع

مطالعه بیشتر
مقایسه کامل و جامع MySQLi و PDO در PHP: کدام یک برای پروژه شما مناسب‌تر است؟
1405/05/04 23:45

مقایسه کامل و جامع MySQLi و PDO در PHP: کدام یک برای پروژه شما مناسب‌تر است؟

مطالعه بیشتر
آموزش استفاده از object-fit و object-position در CSS: تنظیم و قرارگیری تصاویر به‌صورت دقیق
1403/08/12 19:51

آموزش استفاده از object-fit و object-position در CSS: تنظیم و قرارگیری تصاویر به‌صورت دقیق

مطالعه بیشتر
اصول پایه React.js: آشنایی با کامپوننت‌ها، وضعیت و رندرینگ
1402/06/28 23:20

اصول پایه React.js: آشنایی با کامپوننت‌ها، وضعیت و رندرینگ

مطالعه بیشتر
آموزش صفر تا صد ساخت ماشین حساب با جاوا اسکریپت (پروژه محور و کاربردی)
1405/03/13 23:55

آموزش صفر تا صد ساخت ماشین حساب با جاوا اسکریپت (پروژه محور و کاربردی)

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

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

مطالعه بیشتر
آموزش کامل دستورات شرطی در PHP: راهنمای جامع if، else و elseif
1405/04/04 00:05

آموزش کامل دستورات شرطی در PHP: راهنمای جامع if، else و elseif

مطالعه بیشتر
آموزش کامل ثابت‌ها در PHP: تفاوت عمیق define و const طبق استانداردهای گوگل
1405/03/24 01:10

آموزش کامل ثابت‌ها در PHP: تفاوت عمیق define و const طبق استانداردهای گوگل

مطالعه بیشتر
آموزش جامع انواع داده‌ها در PHP (بخش اول: String, Integer, Float, Boolean)
1405/03/24 01:01

آموزش جامع انواع داده‌ها در PHP (بخش اول: String, Integer, Float, Boolean)

مطالعه بیشتر

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