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

السؤال

نشر

السلام عليكم

الاخوة الكرام ارغب في المساعدة في سد وترقيع ثغرة sql injection في صفحة واحدة فقط في الموقع وهذا الاختراق لايتم الا عن طريق الفحص بأداه sql map اما في المتصفح فقد تم ترقيع الثغرة بأكثر من وسيلة والثغرة موجودة لاني اقوم بستخدام دالة $GET في تمرير المعلومات من الصفحة الرئيسية الى صفحة التفاصيل

Recommended Posts

  • 0
نشر

وعليكم السلام ورحمة الله وبركاته.

بما أنك تستخدم $_GET لتمرير المعلومات من الصفحة الرئيسية إلى صفحة التفاصيل فهذا هو نقطة ضعف لديك في الموقع يمكن استغلالها من خلال sql injection وذلك في حال لم تكن البيانات المدخلة لم يتم تحضيرها و معالجتها بشكل صحيح.

يجب عليك استخدام الاستعلامات (Prepared Statements) مع قاعدة البيانات وذلك يساهم بشكل كبير في منع ثغرة SQL Injection. بدل من كتابة المدخلات $_GET مباشرة في الاستعلام والتي من الممكن أن تحتوي على أكواد sql لحقنها .ويتم إعداد الاستعلام أولا مع علامات مبدئية ثم تمرير القيم بعد ذلك.

مثال عن طريق إستخدام PDO :

<?php
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);

// تحضير الاستعلام
$stmt = $pdo->prepare("SELECT * FROM table WHERE id = :id");
$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['my_column'];

لاحظ كيف إستخدمنا دالة prepare() وهي دالة تستخدم لتحضير استعلام SQL قبل تنفيذه بطريقة تفصل بين الاستعلام نفسه و البيانات المدخلة من المستخدم والهدف الأساسي منها هو حماية قاعدة البيانات من أي مدخلات ضارة أو غير متوقعة من المستخدم.

والطريقة الثانية من خلال التحقق من المدخلات فمثلا لنتتحقق مثلا أن ال id المرسل في $_GET هو رقم هكذا مثلا :

if (isset($_GET['id']) && is_numeric($_GET['id'])) {
    $id = $_GET['id'];
    // تنفيذ الأكواد التي تريدها
}

 

  • 0
نشر

للاسف الطريقة الثانية غير ناجحة

 

الطريقة الاولى لايتم النجاح في عرض القيم التي تم الاستعلام عنها مثل الصور او قيمة العنوان او قيمة المحتوى

  • 0
نشر
  بتاريخ On 14‏/4‏/2025 at 10:42 قال m_sh:

للاسف الطريقة الثانية غير ناجحة

 

الطريقة الاولى لايتم النجاح في عرض القيم التي تم الاستعلام عنها مثل الصور او قيمة العنوان او قيمة المحتوى

أظهر المزيد  

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

يرجى إرفاق الكود لنرى أين المشكلة . حيث يجب أن تعمل الطريقة الأولى دون أى مشاكل.

  • 0
نشر (معدل)

ولتوضيح بشكل اكبر هذا هو الكود

<?php

error_reporting(0);
ini_set('display_errors', 0);

include_once('config.php') ;

$id = $_GET['id'] ;

if (isset($_GET['t']) && is_numeric($_GET['t'])) {

$allowedPage = array('Listcontent.php');
$Record = mysqli_query($conn,"SELECT * FROM `content` WHERE id= $id");
$data = mysqli_fetch_array($Record);

}
else{
    
    header ("Location:index");
 echo '<meta http-equiv="refresh" content="0;url=index">';
    
}
تم التعديل في بواسطة محمد عاطف17
تنسيق الشيفرة
  • 0
نشر
  بتاريخ On 14‏/4‏/2025 at 10:42 قال m_sh:

للاسف الطريقة الثانية غير ناجحة

الطريقة الاولى لايتم النجاح في عرض القيم التي تم الاستعلام عنها مثل الصور او قيمة العنوان او قيمة المحتوى

أظهر المزيد  

الأمر غير واضح سببه، قم بإرفاق كود الاستعلام لتفقد سبب المشكلة.

عامًة استخدم قيمة id صالحة من قاعدة البيانات لديك، وقم بتشغيل الاستعلام التالي مباشرة في أداة مثل phpMyAdmin أو أي عميل SQL آخر، وفي حال لم يقم الاستعلام بإعادة البيانات المتوقعة، فالمشكلة في الاستعلام نفسه أو البيانات في قاعدة البيانات.

أو بعد سطر $row = $stmt->fetch(PDO::FETCH_ASSOC) أضف التالي:

echo "<pre>";
print_r($row);
echo "</pre>";

لعرض محتويات المتغير $row بالضبط، ولو طبع bool(false)، فيعني أنه لم يتم العثور على صف.

ولو طبع مصفوفة، فسترى أسماء الأعمدة الفعلية وقيمها، تفقد هل هي مطابقة لقاعدة البيانات أم لا؟

  • 0
نشر
  بتاريخ On 14‏/4‏/2025 at 11:03 قال m_sh:

ولتوضيح بشكل اكبر هذا هو الكود

<?php

error_reporting(0);
ini_set('display_errors', 0);

include_once('config.php') ;

$id = $_GET['id'] ;

if (isset($_GET['t']) && is_numeric($_GET['t'])) {

$allowedPage = array('Listcontent.php');
$Record = mysqli_query($conn,"SELECT * FROM `content` WHERE id= $id");
$data = mysqli_fetch_array($Record);

}
else{
    
    header ("Location:index");
 echo '<meta http-equiv="refresh" content="0;url=index">';
    
}
 
أظهر المزيد  

لاحظ أنني وضعت ال $_GET['id'] كمثال لأني لم أعرف ما الكود الذي لديك . وكان ينبغي عليك أن تقوم بتعديل الكود لديك ليناسب الطريقة التي وضحتها لك .

لاحظ أنك تستقبل البيانات من $_GET['t']  ولكنك في الإستعلام تضع ال id لهذا بالطبع لن يعمل .

<?php

error_reporting(0);
ini_set('display_errors', 0);

include_once('config.php');

$t = $_GET['t'];

$allowedPage = array('Listcontent.php');

$stmt = mysqli_prepare($conn, "SELECT * FROM `content` WHERE id = ?");
mysqli_stmt_bind_param($stmt, "s", $t); // "s" تعني أن المتغير سلسلة نصية (string)
mysqli_stmt_execute($stmt);

$result = mysqli_stmt_get_result($stmt);
$data = mysqli_fetch_array($result);

mysqli_stmt_close($stmt);

إليك الكود السابق بإستخدام mysqli وليس pdo ولكن الأفضل إستخدام pdo

  • 0
نشر
  بتاريخ On 14‏/4‏/2025 at 11:03 قال m_sh:

ولتوضيح بشكل اكبر هذا هو الكود

<?php

error_reporting(0);
ini_set('display_errors', 0);

include_once('config.php') ;

$id = $_GET['id'] ;

if (isset($_GET['t']) && is_numeric($_GET['t'])) {

$allowedPage = array('Listcontent.php');
$Record = mysqli_query($conn,"SELECT * FROM `content` WHERE id= $id");
$data = mysqli_fetch_array($Record);

}
else{
    
    header ("Location:index");
 echo '<meta http-equiv="refresh" content="0;url=index">';
    
}
أظهر المزيد  

هل يتم استقبال البيانات من id أم من t ؟ سأفترض أنه الـ id.

عامًة لا يتم استخدام PDO،  بل دوال mysqli_* القديمة،  والأهم يوجد ثغرة SQL Injection واضحة.

تستقبل القيمة مباشرًة من المستخدم هنا دون تحويله إلى INT أي رقم صحيح ولا تتحقق من جوده:

$id = $_GET['id'];

ثم تضع المتغير $id مباشرة في نص الاستعلام، بالتالي أي أحد يستطيع إرسال قيمة مثل 1 OR 1=1 في باراميتر id لسحب كل المحتوى، أو أسوأ من ذلك.

$Record = mysqli_query($conn,"SELECT * FROMcontentWHERE id= $id");

أيضًا يتم جلب البيانات إلى المتغير $data باستخدام mysqli_fetch_array($Record), لكن لا يقوم بطباعة أو استخدام أي عمود من البيانات، لذا لا يتم ظهور أي شيء في المتصفح حتى لو نجح الاستعلام.

بالإضافة إلى إخفاء الأخطاء في error_reporting(0); ini_set('display_errors', 0) ولن تتمكن من معرفة سبب عدم عمل الكود أثناء التطوير.

<?php
 //تمكين عرض الأخطاء مؤقتاً للتطوير فقط
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

include_once('config.php');

$id = null;
$t_is_valid = false;

if (isset($_GET['id']) && filter_var($_GET['id'], FILTER_VALIDATE_INT) && $_GET['id'] > 0) {
    $id = (int)$_GET['id'];
}

if (isset($_GET['t']) && is_numeric($_GET['t'])) {
    $t_is_valid = true;
}

if ($id !== null && $t_is_valid) {
    if ($conn && $conn instanceof mysqli) {
        $sql = "SELECT title, content, image_path FROM `content` WHERE id = ?";
        $stmt = $conn->prepare($sql);

        if ($stmt) {
            $stmt->bind_param("i", $id);
            $stmt->execute();
            $result = $stmt->get_result();
            $data = $result->fetch_assoc();

            if ($data) {
                echo "<h1>" . htmlspecialchars($data['title']) . "</h1>";
                echo "<div>" . htmlspecialchars($data['content']) . "</div>";
                if (!empty($data['image_path'])) {
                    echo "<img src='" . htmlspecialchars($data['image_path']) . "' alt='" . htmlspecialchars($data['title']) . "'>";
                }
            } else {
                echo "لم يتم العثور على محتوى بالمعرف (ID) المحدد.";
            }

            $stmt->close();
        } else {
            echo "خطأ في إعداد الاستعلام: " . htmlspecialchars($conn->error);
        }

        $conn->close();
    } else {
         echo "خطأ: مشكلة في الاتصال بقاعدة البيانات.";
    }
} else {
    header("Location: index.php");
    exit;
}
?>

أضفت htmlspecialchars  لحماية مخرجات HTML لمنع ثغرات XSS.

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...