مقدمة
ورقة غش XSS المستندة إلى DOM هي مرجعك المفضل عندما تريد تحديد موقع ومنع وأتمتة الحماية من حقن البرامج النصية من جانب العميل. في جوهرها: تحديد مكان الإدخال الذي يتحكم فيه المستخدم (أ المصدر) يتدفق إلى واجهة برمجة تطبيقات خطرة (أ الحوض)، استبدلها بأنماط آمنة (استخدم محتوى النص, إنشاء عنصرأو المطهرات)، ودمج عمليات التحقق في سير عمل الإنشاء ووقت التشغيل والاختبار الخماسي. نظرًا لأن DOM XSS يحدث بالكامل في المتصفح ويتجاوز العديد من عوامل التصفية التقليدية من جانب الخادم، تصبح الواجهة الأمامية خط الدفاع الأخير، والمكان الذي لا تزال معظم الفرق تفتقر فيه إلى الأتمتة.
ما هو XSS المستند إلى DOM وسبب أهميته
وفقًا ل PortSwigger، تنشأ البرمجة النصية العابرة للمواقع المستندة إلى DOM عندما "جافا سكريبت" تأخذ البيانات من مصدر يمكن التحكم فيه من قبل المهاجم، مثل عنوان URL، وتمررها إلى مصرف يدعم تنفيذ التعليمات البرمجية الديناميكية، مثل eval() أو داخليHTML." portswigger.net تؤكّد ورقة الغشّ في الوقاية من XSS المستندة إلى DOM المستندة إلى DOM من OWASP على أن الفرق الرئيسي عن XSS المخزّنة/المرجعية هو الحقن من جانب العميل في وقت التشغيل. cheatsheetsheetseries.owasp.org+1
في التطبيقات الحديثة - تطبيقات الصفحة الواحدة (SPAs)، والاستخدام المكثف لأدوات الطرف الثالث، وبناء DOM الديناميكي - تزداد المخاطر: قد لا تصل الحمولات إلى سجلات الخادم أبدًا، وقد لا تصل إلى سجلات الخادم الخاص بك، وقد لا تراعيها برامج WAFs التقليدية، وغالبًا ما لا يراعي المطورون بشكل كافٍ معرِّفات الأجزاء, تدفقات ما بعد الرسالةأو اسم النافذةجميع المصادر المشتركة. إن إدراك هذا التحول هو الخطوة الأولى نحو قياس نضجك الأمني.
رسم خريطة التهديد: المصادر → المصارف
يبدأ الترميز الآمن بخريطة ذهنية لـ المصادر (حيث تدخل مدخلات المهاجم) و المغاسل (حيث يحدث التنفيذ). تلخص إحدى المدونات الأمنية ما يلي: "المصدر هو أي مكان على صفحة الويب حيث يمكن إضافة مدخلات المستخدم... والمصدر هو المكان الذي تذهب إليه البيانات المدرجة في المصدر... وإذا لم يتم تعقيمها يمكن أن تؤدي إلى ثغرة XSS المستندة إلى DOM." متوسط
فيما يلي جدول مدمج يجب أن تحتفظ به في محطة عملك وفي قوائم المراجعة:
| المصدر (نقطة الدخول) | مغسلة (واجهة برمجة تطبيقات خطرة) |
|---|---|
| تجزئة الموقع، والبحث عن الموقع، وURLSearchParams | داخليHTML، وإدراج متجاورHTML، وخارجيHTML |
| ما بعد الرسالة, اسم النافذة | eval()، دالة جديدة()، setTimeout(string) |
| مرجع المستند، مخزن محلي، مخزن محلي، مخزن الجلسة | setAttribute('on...')، element.src = ... |
| بيانات أداة الطرف الثالث التي لم يتم فحصها من طرف ثالث | أي إدراج DOM أو تنفيذ كود ضمني أو تنفيذ رمز ضمني |
كما تؤكد OWASP، لا توجد تقنية واحدة تمنع XSS: يجب عليك الجمع بين المصارف المناسبة، والترميز، والتعقيم، وواجهات برمجة التطبيقات الآمنة. cheatsheetsheetseries.owasp.org
أنماط الهجوم في العالم الحقيقي مع التعليمات البرمجية والإصلاحات
المثال أ - حقن محدد jQuery عبر جزء عنوان URL
مقتطفات ضعيفة
ياءات
$(window).on('hashchange', () => {
const target = $(location.hash) ؛ // يتحكم فيه المستخدم
الهدف[0].scrollIntoView();
});
قد يقوم المهاجم بصياغة https://site/page.html#<img src="x" onerror="alert(1)"> - يتعامل jQuery مع التجزئة كـ HTML/محدد و على خطأ المشغلات.
إصلاح:
ياءات
خام = الموقع.hash.slice(1);
const safeId = /^[A-Za-Z0-9_-]+$/.test(raw)؟ خام : فارغ;
إذا (معرف آمن) {
const target = document.getElementByIlementById(safeId);
إذا كان (الهدف) target.scrollIntoView();
}
المفتاح: التحقق من الصحة، والتعامل مع التجزئة كمعرف وليس HTML.
المثال ب - ما بعد الرسالة → سلسلة التقييم
مقتطفات ضعيفة
ياءات
window.addEventEventListener('message'، e => {
eval(e.data)؛ // خطير
});
نسخة ثابتة:
Window.addEventEventListener('message'، الحدث => {
إذا (إذا كان (event.origin.origin !== '') يتم الإرجاع;
جرب {
const msg = JSON.parse(event.data);
التعامل مع الرسالة(msg);
} التقاط {
console.warn('تنسيق الرسالة غير صالح');
}
});
تجنب التقييموالتحقق من الأصل، واستخدام التحليل الآمن.
المثال ج - المحرر/معاينة XSS في سياق تخفيض السعر
عرضة للخطر:
ياءات
معاينة.innerHTML = تم وضع علامة (userInput);
آمن:
ياءات
استيراد DOMPurify من 'dompurify';
قذر = تم وضع علامة (إدخال المستخدم);
نظيف = DOMPurify.sanitize(قذر);
معاينة.innerHTML = نظيف;
عند السماح بإنشاء HTML من قِبل المستخدم، فإن التعقيم مطلوب.
عمليات التنفيذ القابلة للنشر: جعلها عملية
مساعد DOM الآمن DOM - Safe-dom.js
ياءات
استيراد DOMPurify من 'dompurify';
تصدير دالة التصدير setSafeHTML(el, dirty) {
const clean = DOMPurify.sanitize.sanitize(قذر، {
العلامات المسموح بها: ['b','i','a','p','ul','li','code','pre','img'],
ALLOWED_ATTR: ['href','src','src','alt','title','rel'],
FORBID_ATTR: ['onror','onclick','style']
});
el.innerHTML = نظيف;
}
تصدير دالة التصدير setText(el، نص) {
el.textContentent = String(text ?? '');
}
تصدير الدالة SafeSetAttribute(el, name, val) {
إذا (/^ على//i.test(name)) قم بإلقاء خطأ جديد('سمة معالج الحدث غير مسموح بها');
el.setAttribute(name, String(val));
}
استخدم هذه المكتبة لمركزية عمليات DOM الآمنة وتقليل الأخطاء البشرية.
الإنفاذ الثابت - عينة ESLint
ياءات
// .eslintrc.js
القواعد: {
'لا-مقيد-منطوق-مقيد': [
"خطأ",
{محدد: "AssignmentExpression[left.property.name='innerHTML']"، رسالة: "استخدم safe-dom.setSafeHTML أو textContent." },
{محدد: "CallExpression[callee.name='eval']"، رسالة: "تجنب eval()"},
{محدد: "CallExpression[callee.property.name='write']"، رسالة: "تجنب المستند.write()" }
]
}
ادمج مع خطافات ما قبل الالتزام (أجش, مرحلياً على مراحل) لمنع الأنماط الخطرة.
اختبار CI / اختبار Puppeteer - إجراءات GitHub
.github/workflows/dom-xss.yml يؤدي إلى تشغيل اختبار الدمى المتحركة:
// اختبارات/puppeteer/dom-xss-test.js
ياءات
مُحرِّك الدمى = يتطلب('محرك الدمى');
(متزامن ()>{{
متصفح const = انتظر puppeteer.launch();
const page = انتظر المتصفح.newPage();
تشكل السجلات = [];
page.on('console', msg => logs.push(msg.text()));
انتظر page.goto(${URL}/page.html.html#<img src="x" onerror="console.log("xss")">);
انتظر الصفحة.waitForTimeout(1000);
إذا (logs.some(l=>l.includes('XSS')))) process.exit(2);
انتظر المتصفح.أغلق();
})();
فشل في البناء على الكشف.
مراقبة وقت التشغيل - MutationObserver
ياءات
(الدالة(){
const obs = جديد MutationObserver(muts=>{{
muts.forEach(m=>>{
m.addedNodes.forEach(n=>>{
إذا كان (n.n.nodeType====1){ {
const html = n.innerHTML | | '';
إذا (/ على(/على(|خطأ |نقر |تحميل)|<<نص//ب/i.test(html)}) {
navigator.sendBeacon('/_monitoring/xss', JSON.stringify({
عنوان url: site.href، مقتطف: html.slice(0,200)
}));
}
}
});
});
});
Observe.observe(document.documentElement, {قائمة الأطفال:صحيح، الشجرة الفرعية:صحيح});
})();
مفيد في التدريج لتنبيه حقن DOM غير المتوقعة.
تقوية أمان المتصفح - CSP والأنواع الموثوق بها
رأس CSP:
بي جي إس كيو إس كيو إل
سياسة المحتوى-الأمان-المحتوى: افتراضي-المصدر "ذاتي"؛ نص-المصدر "ذاتي" "nonce-XYZ"؛ كائن-المصدر "لا شيء"؛ قاعدة-وري "ذاتي";
مقتطفات الأنواع الموثوق بها:
ياءات
window.trustedTypes?.createPolicy('safePolicy', {
createHTML: s => { طرح خطأ جديد ('تم حظر تعيين HTML المباشر')؛ },
createScript: s => { طرح خطأ جديد ('تم حظر إنشاء نص برمجي مباشر')؛ }؛ }
});
هذا ينفي المصارف غير الموثوق بها افتراضيًا.
سلامة النص البرمجي للغير - SRI
باش
opensl dgst -sha384 -sha384 -ثنائي vendor.js | opensl base64 -A
الاستخدام سكريبت> للتثبيت والتحقق
التكامل مع Penligent للتشغيل الآلي
إذا كان فريقك يستخدم Penligent، فيمكنك رفع مستوى حماية DOM XSS إلى خط أنابيب مستمر. تشير مقالة Penligent البحثية إلى كيفية "الكشف عن XSS المستند إلى DOM من خلال تتبع عيب وقت التشغيل... لا يمكن لتقنيات جانب الخوادم أن تكشف بشكل موثوق الحقن من جانب العميل." بنليجنت
مثال على سير العمل:
- في CI قم بتشغيل فحص Penligent باستخدام مجموعة القواعد
دوم-إكس إس إس إستوريد حمولات مثل#<img src="x" onerror="alert(1)">. - يقوم Penligent بتنفيذ تدفقات بدون رأس، وإنشاء PoC، وإرجاع النتائج عبر خطاف الويب.
- نتائج تحليلات CI: إذا كانت درجة الخطورة ≥ عالية، يتم فشل الإنشاء وإضافة تعليق توضيحي للعلاقات العامة مع الحمولة + الحوض + توصية بالإصلاح (على سبيل المثال، "استبدال
داخليHTMLمعآمنة-دوم.setSafeHTML). - يقوم المطورون بالإصلاح، وتشغيل CI مرة أخرى، والدمج فقط عندما يكون لونه أخضر.
وهذا يغلق الحلقة: من المرجع (ورقة الغش هذه) → سياسة التعليمات البرمجية → الكشف الآلي → المعالجة المنظمة.
الخاتمة
لم تعد الواجهة الأمامية "مجرد واجهة مستخدم". بل هي سطح هجوم. ترشدك ورقة الغش هذه إلى فهم الحقن من جانب العميل، واستبدال البالوعات الخطرة، وبناء مكتبات مساعدة آمنة، ونشر الكشف الثابت/المعلوماتية/وقت التشغيل، والأتمتة باستخدام منصة مثل Penligent. خطواتك التالية: افحص قاعدة التعليمات البرمجية الخاصة بك بحثًا عن البالوعات المحظورة (داخليHTML, التقييم)، اعتمد أمان-دوم المكتبة، وفرض قواعد الوبر، ودمج الاختبارات بدون رأس ومنطق الاختبار الخماسي الحقيقي، ومراقبة الإنتاج/التدريج، وتثبيت موارد الطرف الثالث. تتعلّق حماية DOM XSS بجعلها مستحيل للتسلل - وليس فقط الاعتماد على الصدفة.

