اذهب إلى المحتوى

السؤال

نشر

إذا تم إدراج إدخال المستخدم بدون تعديل في استعلام SQL، يصبح التطبيق عرضة لحقن SQL، كما في المثال التالي:

$unsafe_variable = $_POST['user_input'];

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");

ذلك لأن المستخدم قد يدخل شيئًا مثل value'); DROP TABLE table;--، وبذلك يصبح الاستعلام كما يلي:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

ما الذي يمكن فعله لتجنب حدوث ذلك؟

Recommended Posts

  • 1
نشر
بتاريخ On 27‏/12‏/2023 at 06:04 قال Khaled Osama3:

يمكنك استخدام أمر prepared statements في MySQLi أو PDO. فهي تفصل البيانات عن الاستعلام مما يمنع حقن الSQL.

// افتراضًا أن $mysqli هو الاتصال بقاعدة البيانات
$unsafe_variable = $_POST['user_input'];

// استخدام استعلام معد مسبقًا
$stmt = $mysqli->prepare("INSERT INTO `table` (`column`) VALUES (?)");

// ربط القيمة بشكل آمن
$stmt->bind_param("s", $unsafe_variable);

// تنفيذ الاستعلام
$stmt->execute();

// إغلاق الاستعلام
$stmt->close();

او تعديل الإدخالات قبل إدراجها في الاستعلام. مثل إزالة الرموز خاصة وتحويل الأقواس إلى نص.

$user_input = strip_tags($unsafe_variable);
$user_input = mysqli_real_escape_string($conn, $user_input);

$query = "INSERT INTO table (column) VALUES ('$user_input')";

بعد استخدام strip_tags، يتم إزالة أي علامات HTML (إذا كانت موجودة).

مثلا المستخدم أدخل النص التالي:

$user_input = '<script>alert("Hello, this is a malicious script!");</script><p>This is some text.</p>';

سيتم إزالة جميع العلامات HTML وPHP، وبالتالي، ستكون قيمة $user_input بعد استخدام strip_tags هي:

$user_input = 'alert("Hello, this is a malicious script!");This is some text.';

بعد استخدام mysqli_real_escape_string، تصبح الرموز الخاصة معتبرة جزءًا من البيانات وليست جزءًا من الكود SQL، مما يمنع حقن الشيفرة SQL ويحافظ على سلامة الاستعلام وقاعدة البيانات.

فمثلا الاستعلام قبل استخدام `mysqli_real_escape_string`:

$user_input = "'; DROP TABLE users; --";
$query = "INSERT INTO table (column) VALUES ('$user_input')";

إذا تم تمرير هذا الاستعلام إلى قاعدة البيانات كما هو، فإنه يتضمن توجيه إضافي لحقن الشيفرة SQL، ويحاول حذف جدول المستخدمين (`DROP TABLE users`)، مما يسبب فقدان البيانات.

الآن، إذا تم استخدام `mysqli_real_escape_string`:

$user_input = "'; DROP TABLE users; --";
$user_input = mysqli_real_escape_string($conn, $user_input);
$query = "INSERT INTO table (column) VALUES ('$user_input')";

فإن `mysqli_real_escape_string` سيقوم بتهيئة `$user_input` بحيث تتم معالجة الرموز الخاصة في النص بشكل صحيح. النتيجة ستكون:

$user_input = "\'; DROP TABLE users; --";
$query = "INSERT INTO table (column) VALUES ('$user_input')";

ويفضل ان تحقق من نوع البيانات:

if(is_int($user_input)) {
  $user_input = (int) $user_input;
}

$query = "INSERT... $user_input";

الأفضل دائما استخدام طرق موثوقة للتعامل مع البيانات مثل prepared statements.

خطاء في الكود :

<!DOCTYPE html>
<html lang="ar">
<head>
    <link rel="icon" href="https://c0.klipartz.com/pngpicture/573/614/gratis-png-ng%C5%A9-hanh-s%C6%A1n-distrito-casa-apartamento-inmobiliaria-volta-redonda-venta-de-logotipos-de-bienes-raices.png" />
    <title>موقع تجريبي</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@300&display=swap" rel="stylesheet">
    <meta charset="utf-8" />
    <link rel="stylesheet" type="text/css" media="screen" href="home.css">
</head>
<body>
    <header>
        <div>
            <img src="a.png" alt="نظام ">
        </div>
        <center>
            <div>
                <button>نقاط البيع</button>
                <button>أدارة المخزون</button>
                <button>3</button>
                <button>الشيكات</button>
                <button>الأستاذ العام</button>
                <button>إدارة النظام</button>
            </div>
        </center>
    </header>

    <?php
    $server = 'DESKTOP-PJDLJNR';
    $database = 'Legacy';
    $username = '';
    $password = '';

    $connection = new PDO("sqlsrv:Server=$server;Database=$database", $username, $password);
    if (!$connection) {
    die(print_r(sqlsrv_errors(), true));
    }
    $sql_query = 'SELECT * FROM Problemss';
    $statement = $connection->query($sql_query);
    ?>

    <table border="1" width="100%">
        <tr>
            <th>تم</th>
            <th>الحلول</th>
            <th>المشكلة</th>
            <th>م</th>
            <th>الرقم</th>
        </tr>

        

        <?php
        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        print_r($row);
        <tr>
            <td><?php echo $row['تم']?></td>
            <td><?php echo $row['الحلول']?></td>
            <td><?php echo $row['المشكلة']?></td>
            <td><?php echo $row['م']?></td>
            <td><?php echo $row['الرقم']?></td>
        </tr>
        }
        $connection->close();
        ?>
    </table>
</body>
</html>

 

  • 0
نشر
بتاريخ 13 ساعة قال Abdelrahman Mostafa10:

إذا تم إدراج إدخال المستخدم بدون تعديل في استعلام SQL، يصبح التطبيق عرضة لحقن SQL، كما في المثال التالي:

$unsafe_variable = $_POST['user_input'];

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");

ذلك لأن المستخدم قد يدخل شيئًا مثل value'); DROP TABLE table;--، وبذلك يصبح الاستعلام كما يلي:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

ما الذي يمكن فعله لتجنب حدوث ذلك؟

يمكنك استخدام أمر prepared statements في MySQLi أو PDO. فهي تفصل البيانات عن الاستعلام مما يمنع حقن الSQL.

// افتراضًا أن $mysqli هو الاتصال بقاعدة البيانات
$unsafe_variable = $_POST['user_input'];

// استخدام استعلام معد مسبقًا
$stmt = $mysqli->prepare("INSERT INTO `table` (`column`) VALUES (?)");

// ربط القيمة بشكل آمن
$stmt->bind_param("s", $unsafe_variable);

// تنفيذ الاستعلام
$stmt->execute();

// إغلاق الاستعلام
$stmt->close();

او تعديل الإدخالات قبل إدراجها في الاستعلام. مثل إزالة الرموز خاصة وتحويل الأقواس إلى نص.

$user_input = strip_tags($unsafe_variable);
$user_input = mysqli_real_escape_string($conn, $user_input);

$query = "INSERT INTO table (column) VALUES ('$user_input')";

بعد استخدام strip_tags، يتم إزالة أي علامات HTML (إذا كانت موجودة).

مثلا المستخدم أدخل النص التالي:

$user_input = '<script>alert("Hello, this is a malicious script!");</script><p>This is some text.</p>';

سيتم إزالة جميع العلامات HTML وPHP، وبالتالي، ستكون قيمة $user_input بعد استخدام strip_tags هي:

$user_input = 'alert("Hello, this is a malicious script!");This is some text.';

بعد استخدام mysqli_real_escape_string، تصبح الرموز الخاصة معتبرة جزءًا من البيانات وليست جزءًا من الكود SQL، مما يمنع حقن الشيفرة SQL ويحافظ على سلامة الاستعلام وقاعدة البيانات.

فمثلا الاستعلام قبل استخدام `mysqli_real_escape_string`:

$user_input = "'; DROP TABLE users; --";
$query = "INSERT INTO table (column) VALUES ('$user_input')";

إذا تم تمرير هذا الاستعلام إلى قاعدة البيانات كما هو، فإنه يتضمن توجيه إضافي لحقن الشيفرة SQL، ويحاول حذف جدول المستخدمين (`DROP TABLE users`)، مما يسبب فقدان البيانات.

الآن، إذا تم استخدام `mysqli_real_escape_string`:

$user_input = "'; DROP TABLE users; --";
$user_input = mysqli_real_escape_string($conn, $user_input);
$query = "INSERT INTO table (column) VALUES ('$user_input')";

فإن `mysqli_real_escape_string` سيقوم بتهيئة `$user_input` بحيث تتم معالجة الرموز الخاصة في النص بشكل صحيح. النتيجة ستكون:

$user_input = "\'; DROP TABLE users; --";
$query = "INSERT INTO table (column) VALUES ('$user_input')";

ويفضل ان تحقق من نوع البيانات:

if(is_int($user_input)) {
  $user_input = (int) $user_input;
}

$query = "INSERT... $user_input";

الأفضل دائما استخدام طرق موثوقة للتعامل مع البيانات مثل prepared statements.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...