انتقل إلى محتوى الدرس
الدرس 87
دورة PHP

الوقاية من ثغرات XSS وترميز المخرجات حسب السياق في PHPPHP XSS Prevention and Context-Aware Output Escaping

اقضِ على ثغرات حقن السكريبتات العابرة للمواقع XSS في PHP 8 باستخدام htmlspecialchars وفحص الروابط ورؤوس الحماية القياسية.
أقسام الدرس
6
الأمثلة
6
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

تحدث ثغرة البرمجة العابرة للمواقع (XSS) عندما يطبع تطبيق الويب بيانات غير موثوقة داخل الصفحة دون ترميز، مما يسمح للمهاجم بتنفيذ كود JavaScript داخل متصفح الضحية.

  • ثغرة XSS المنعكسة (Reflected): تُطبع المدخلات الخبيثة القادمة في الطلب الحالي (مثل $_GET["q"]) مباشرة داخل صفحة الاستجابة.
  • ثغرة XSS المخزنة (Stored): تُحفظ المدخلات الخبيثة في قاعدة البيانات (مثل تعليق أو نبذة شخصية) وتُنفذ في متصفح كل زائر يستعرض الصفحة.
  • القاعدة الذهبية: تحقق من المدخلات عند الاستقبال، وخزّن البيانات الخام في قاعدة البيانات عبر PDO، ورمّز المخرجات لحظة الطباعة في القالب.

بدلاً من تفسير <script> كوسم برمجي قابل للتنفيذ، يعرضه المتصفح كنص عادي غير ضار على الشاشة.

مخطط توضيحي: محاكي ترميز المخرجات والوقاية من ثغرات XSS في PHP
PHP
<?php
$searchQuery = '<script>alert("XSS")</script>';

// VULNERABLE: Echoing raw input directly into HTML
// echo "Results for: " . $searchQuery;

// SECURE: Escaping special HTML characters on output
$safeQuery = htmlspecialchars($searchQuery, ENT_QUOTES, 'UTF-8');
echo "Results for: " . $safeQuery . "\n";

الأداة الأساسية للوقاية من XSS في قوالب PHP هي الدالة htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, "UTF-8") التي تحول الرموز الخمسة الحساسة في HTML إلى كيانات نصية آمنة.

  • تحول الرمز & إلى &amp;، و< إلى &lt;، و> إلى &gt;، وعلامتي التنصيص المزدوجة والمفردة إلى كيانات آمنة.
  • أصبحت الأعلام ENT_QUOTES | ENT_SUBSTITUTE والترميز "UTF-8" افتراضية منذ PHP 8.1+، ويُفضل تمريرها صراحة لوضوح الكود.
  • عرّف دالة مساعدة مختصرة e(string $val): string لتسهيل ترميز كل متغير يُطبع في القوالب.

تتعامل الدالة المساعدة e() بأمان مع القيم الفارغة null، وترمّز علامات التنصيص المزدوجة والمفردة والأقواس الزاوية.

PHP
<?php
function e(?string $value): string {
    return htmlspecialchars(
        (string) $value,
        ENT_QUOTES | ENT_SUBSTITUTE,
        'UTF-8'
    );
}

$bio = 'O\'Reilly & "Friends" <Admin>';
echo e($bio) . "\n";

تتطلب السياقات المختلفة في الصفحة قواعد ترميز مناسبة لكل منها؛ فاحرص دائماً على إحاطة خصائص HTML بعلامات تنصيص، واستخدم json_encode() مع أعلام الترميز السداسي عند تمرير بيانات PHP إلى JavaScript.

  • أحِط قيم خصائص HTML دائماً بعلامات تنصيص مزدوجة value="<?= e($val) ?>"؛ لأن الخصائص غير المحاطة بعلامات تنصيص يمكن اختراقها بمجرد إضافة مسافة.
  • لا تطبع النصوص الخام داخل وسم <script> بالاعتماد على htmlspecialchars() وحدها.
  • استخدم json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) أو مرر البيانات عبر خاصية data-*.

يحول العلم JSON_HEX_TAG الرمزين < و> إلى \u003C و\u003E، مما يمنع إغلاق وسم <script> المحيط.

PHP
<?php
$userData = [
    'username' => 'Sara </script><script>alert(1)</script>',
    'role'     => 'editor',
];

$safeJson = json_encode(
    $userData,
    JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
);
echo "const APP_USER = $safeJson;\n";

توجّه رؤوس الأمان في استجابة HTTP المتصفح لتقييد مصادر تحميل السكريبتات ومنع هجمات تخمين نوع المحتوى (MIME Sniffing).

  • يمنع الرأس Content-Security-Policy: default-src 'self' تشغيل السكريبتات المضمنة غير المصرح بها أو المحملة من نطاقات خارجية.
  • يمنع الرأس X-Content-Type-Options: nosniff المتصفح من تنفيذ الملفات النصية أو الصور المرفوعة كأكواد HTML أو JavaScript.
  • يحمي الرأس X-Frame-Options: DENY (أو توجيه frame-ancestors 'none') صفحاتك من هجمات النقر الخادع (Clickjacking).

في تطبيقات PHP الإنتاجية، مرر كل سطر من هذه السياسات إلى الدالة header($line) قبل إرسال أي مخرجات HTML.

PHP
<?php
$headers = [
    "Content-Security-Policy: default-src 'self'; frame-ancestors 'none'",
    "X-Content-Type-Options: nosniff",
    "X-Frame-Options: DENY",
    "Referrer-Policy: strict-origin-when-cross-origin",
];

foreach ($headers as $line) {
    echo $line . "\n";
}

يُعد التحقق من المدخلات وترميز المخرجات خطي دفاع متكاملين يعملان في نقطتين مختلفتين من دورة حياة الطلب.

  • تحقق من المدخلات فور وصول الطلب لفرض قواعد العمل والأنواع والأطوال والتنسيقات المسموحة.
  • استخدم استعلامات PDO المحضرة عند حفظ البيانات في قاعدة البيانات لمنع حقن SQL.
  • رمّز المخرجات بحسب السياق الدقيق (نص HTML أو خاصية أو رابط أو JSON) لحظة العرض في القالب.

تتحقق filter_var() من كون العمر عدداً صحيحاً ضمن النطاق عند الإدخال، بينما ترمّز htmlspecialchars() الاسم عند الطباعة في HTML.

مرحلة الحمايةالأداة الأساسية في PHPالتهديد المستهدف
Input Validationfilter_var() / preg_match()Malformed data & type errors
Database LayerPDO prepare() + execute()SQL Injection (SQLi)
HTML Body & Quoted Attrhtmlspecialchars(..., ENT_QUOTES)Reflected & Stored XSS
Inline JS Datajson_encode(..., JSON_HEX_TAG)Script breakout XSS
Link href / src URLsparse_url() scheme whitelistjavascript: URI execution

PHP
<?php
$rawAge = "25";
$rawName = 'Ali <Admin>';

$age = filter_var($rawAge, FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 13, 'max_range' => 120],
]);
$safeName = htmlspecialchars($rawName, ENT_QUOTES, 'UTF-8');

echo "User: $safeName (Age: $age)\n";
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

يُعد التحقق من المدخلات وترميز المخرجات خطي دفاع متكاملين يعملان في نقطتين مختلفتين من دورة حياة الطلب. تحقق من المدخلات فور وصول الطلب لفرض قواعد العمل والأنواع والأطوال والتنسيقات المسموحة. استخدم استعلامات PDO المحضرة عند حفظ البيانات في قاعدة البيانات لمنع حقن SQL. رمّز المخرجات بحسب السياق الدقيق (نص HTML أو خاصية أو رابط أو JSON) لحظة العرض في القالب.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 XSS Prevention الوقاية من XSS
اقضِ على ثغرات حقن السكريبتات العابرة للمواقع XSS في PHP 8 باستخدام htmlspecialchars وفحص الروابط ورؤوس الحماية القياسية.
للمراجعة
02 Stored vs Reflected XSS Attacks الفرق بين ثغرات XSS المخزنة والمنعكسة
المفهوم الأساسي لقسم الفرق بين ثغرات XSS المخزنة والمنعكسة في لغة PHP الحديثة.
للمراجعة
03 Escaping HTML with htmlspecialchars ترميز المخرجات النصية بـ htmlspecialchars
الصياغة البرمجية والتطبيق العملي المباشر لقسم ترميز المخرجات النصية بـ htmlspecialchars.
للمراجعة
04 Escaping HTML Attributes and JavaScript تأمين القيم داخل خصائص HTML و JavaScript
قواعد التحقق وأفضل الممارسات القياسية الخاصة بقسم تأمين القيم داخل خصائص HTML و JavaScript.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 PHP PHP
PHP: Hypertext Preprocessor
لغة البرمجة النصية على جانب الخادم لبناء تطبيقات الويب الديناميكية وواجهات البرمجة.
للمراجعة
02 CLI CLI
Command-Line Interface
واجهة سطر الأوامر التي تتيح تشغيل ملفات PHP مباشرة عبر الطرفية.
للمراجعة
03 FPM FPM
FastCGI Process Manager
مدير عمليات FastCGI عالي الأداء لمعالجة طلبات خادم الويب في PHP.
للمراجعة
04 HTML HTML
HyperText Markup Language
لغة الترميز القياسية التي يولدها محرك PHP ويرسلها إلى متصفح العميل بعد التنفيذ.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. أنشئ ملف PHP محلياً ونفّذ المثال البرمجي المشروح في قسم الفرق بين ثغرات XSS المخزنة والمنعكسة للتحقق من المخرجات.

  2. بدّل بين الحالات الثلاث في المحاكي التفاعلي ضمن قسم ترميز المخرجات النصية بـ htmlspecialchars وقارن مخرجات التنفيذ.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

8أسئلة 1أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي8 أسئلة تنتظرك
01

ما الفرق الأساسي بين ثغرة XSS المخزنة (Stored) وثغرة XSS المنعكسة (Reflected)؟

تستمر Stored XSS في قاعدة البيانات بينما تنعكس Reflected XSS من الطلب الحالي مباشرة.

02

ما الدالة والأعلام القياسية في PHP لترميز النصوص غير الموثوقة داخل محتوى HTML والخصائص المحاطة بعلامات تنصيص؟

تقوم هذه الدالة بترميز الرموز الخمسة الحساسة وعلامتي التنصيص بأمان في UTF-8.

03

متى يجب تطبيق ترميز المخرجات بدالة htmlspecialchars()؟

تُحفظ البيانات الخام في قاعدة البيانات عبر PDO وتُرمّز لحظة العرض بحسب السياق.

04

لماذا لا تكفي دالة htmlspecialchars($url) وحدها عند وضع رابط أدخله المستخدم داخل الخاصية href="..."؟

يجب فحص بروتوكول الرابط عبر parse_url والسماح بـ http و https فقط.

05

كيف تمرر مصفوفة أو نصاً من PHP بأمان إلى متغير داخل كود JavaScript؟

تحول هذه الأعلام أقواس الإغلاق وعلامات التنصيص إلى رموز Unicode آمنة.

06

ما الخطر الذي يمنعه رأس الاستجابة X-Content-Type-Options: nosniff؟

يجبر المتصفح على الالتزام الصارم بنوع Content-Type المعلن من الخادم.

07

لماذا يجب دائماً إحاطة قيم خصائص HTML بعلامات تنصيص حتى عند ترميزها بـ htmlspecialchars()؟

لا ترمز htmlspecialchars() المسافات، لذا تظل الخصائص بدون علامات تنصيص قابلة للاختراق.

08

أي رأس استجابة HTTP يوفر دفاعاً قوياً على مستوى المتصفح ضد XSS عبر تقييد مصادر السكريبتات المسموحة؟

تقيد سياسة Content-Security-Policy المصادر المسموح بتحميل وتشغيل السكريبتات منها.