ما هي CSP وكيف تحمي الموقع دون تعطيل وظائفه؟
الكاتب: فريق تحرير Domeny.ForSale تاريخ النشر
باختصار: CSP، أي Content Security Policy، هي آلية أمان في المتصفح تتيح تحديد المصادر التي يمكن للصفحة تحميل الموارد منها، والشيفرة التي يُسمح لها بتنفيذها. تساعد على الحد من آثار XSS، أي حقن نص برمجي دخيل في الصفحة، كما يحمي توجيه مخصص من تضمين الموقع في إطارات غير مرغوب فيها. يُفضّل إرسال السياسة عبر ترويسة استجابة HTTP واختبارها أولًا دون حظر الموارد.
كيف تعمل CSP، وما الذي تحمي منه؟
يحمّل المتصفح عادةً الموارد المحددة في شيفرة الصفحة: النصوص البرمجية وأوراق الأنماط والصور والخطوط. تضيف CSP مجموعة من القواعد إلى هذه العملية. إذا خالف مورد أو أسلوب لتنفيذ الشيفرة هذه السياسة، يحظره المتصفح ويسجّل معلومات عن المخالفة في أدوات المطورين.
أهم استخدامات CSP هو الحد من هجمات XSS (البرمجة النصية عبر المواقع). تقوم هذه الهجمات على جعل نص برمجي للمهاجم يعمل ضمن سياق موقع لا يملكه. فقد تسمح ثغرة في نموذج التعليقات، مثلًا، بإدراج شيفرة JavaScript بدلًا من نص عادي. ويمكن لسياسة CSP صارمة بما يكفي أن تمنع تنفيذ هذه الشيفرة، حتى لو أدرجها التطبيق في الصفحة عن طريق الخطأ.
تساعد CSP أيضًا على التصدي لاختطاف النقرات (clickjacking): تضمين الصفحة داخل إطار، ثم خداع المستخدم للنقر على عناصرها من خلال طبقة مضللة تغطيها. ويتولى التوجيه frame-ancestors توفير هذه الحماية. أما وضع قواعد للنصوص البرمجية وحده فلا يوفرها.
لكن CSP لا تصلح ثغرات التطبيق. فلا يزال من الضروري ترميز بيانات المخرجات بصورة صحيحة، ومعالجة محتوى المستخدمين بأمان، وتحديث البرمجيات. السياسة طبقة حماية إضافية، وليست بديلًا عن هذه الإجراءات.
أين تُضبط سياسة CSP؟
الموضع الموصى به هو ترويسة استجابة HTTP المسماة Content-Security-Policy. ويمكن أن يضيفها التطبيق أو خادم الويب أو الوكيل العكسي أو CDN. ويجب أن تصل الترويسة إلى المتصفح مع مستند HTML الذي تنطبق عليه.
يمكن أيضًا تمرير بعض القواعد عبر الوسم meta باستخدام السمة http-equiv="Content-Security-Policy". لكن لهذا الحل قيودًا: لا يبدأ تطبيق السياسة إلا بعد قراءة الوسم، ولا يدعم وضع الإبلاغ دون حظر، ولا التوجيه frame-ancestors. إذا كان بإمكانك ضبط استجابات HTTP، فاختر الترويسة.
تحقق أيضًا مما إذا كانت طبقة أخرى من البنية التحتية تضيف CSP بالفعل. إذ تُطبّق السياسات المتعددة في الوقت نفسه، ولا تستبدل الترويسة الجديدة سابقتها تلقائيًا. ولذلك قد تفرض قيودًا إضافية على عمل الصفحة.
أهم التوجيهات ومثال على الترويسة
التوجيه هو قاعدة منفردة ضمن السياسة. تُفصل التوجيهات بفواصل منقوطة، وتأتي بعد أسمائها المصادر المسموح بها أو قيم خاصة.
| التوجيه | ما الذي يتحكم فيه؟ |
|---|---|
default-src | المصادر الافتراضية لأنواع عديدة من الموارد التي لم تُحدّد لها قاعدة خاصة |
script-src | مصادر النصوص البرمجية وشروط تنفيذ JavaScript |
style-src | مصادر أوراق الأنماط وقواعد استخدام الأنماط المضمّنة |
img-src | مصادر الصور |
connect-src | الاتصالات التي تبدأ عبر وسائل منها fetch وWebSocket |
object-src | الكائنات المضمّنة التي تتعامل معها عناصر مثل object |
base-uri | العناوين المسموح بها في العنصر base |
frame-ancestors | الصفحات التي يُسمح لها بتضمين المستند داخل إطار |
لموقع بسيط لا يستخدم سوى ملفاته الخاصة، يمكن البدء بالمثال التالي:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
تعني القيمة 'self' الأصل نفسه: تطابق مخطط العنوان واسم المضيف والمنفذ. أما 'none' فلا تسمح بأي مصدر. يمنع المثال أعلاه تضمين الصفحة داخل إطارات، ويحظر، من بين أمور أخرى، النصوص البرمجية المكتوبة مباشرة في HTML وسمات الأحداث مثل onclick.
هذا الإعداد لا يناسب جميع المواقع. إذا كان الموقع يستخدم نظام دفع خارجيًا أو خدمة تحليلات أو خطوطًا خارجية، فيجب تحديد المصادر المطلوبة وإضافتها إلى التوجيهات المناسبة. ولا يحل default-src محل جميع القواعد؛ فالتوجيه frame-ancestors، مثلًا، يتطلب تصريحًا منفصلًا.
كيف تطبّق CSP دون تعطيل الموقع عن غير قصد؟
النهج الأكثر أمانًا هو البدء بتحديد الموارد والخدمات التي يعتمد عليها الموقع فعليًا، ثم تفعيل الحظر لاحقًا.
- احصر الموارد والتكاملات. لا تكتفِ بالصفحة الرئيسية، بل أدرج أيضًا تسجيل الدخول والنماذج والمدفوعات ولوحة المستخدم.
- اضبط الترويسة
Content-Security-Policy-Report-Only. سيقيّم المتصفح السياسة المقترحة ويبلّغ عن المخالفات، لكنه لن يحظر العمليات المخالفة. ويتطلب جمع التقارير تلقائيًا إعدادًا إضافيًا لآلية الإبلاغ والجهة التي تستقبل التقارير. - اختبر سيناريوهات المستخدم كاملة. راجع وحدة التحكم ولوحة الشبكة في المتصفح. وميّز الموارد الضرورية عن التكاملات غير اللازمة والطلبات الصادرة عن إضافات المتصفح.
- صحّح القواعد والشيفرة. بعد الاختبار، انقل السياسة التي تحققت منها إلى
Content-Security-Policy، وراقب الأخطاء بعد نشرها.
لا تتخلص من التحذيرات بإضافة * أو 'unsafe-inline' أو 'unsafe-eval' دون تمحيص. فقد تُضعف هذه الاستثناءات الحماية بدرجة كبيرة. وللنصوص البرمجية المضمّنة الضرورية، يمكن استخدام nonce، وهي قيمة غير قابلة للتوقع تُولّد لكل استجابة، أو hash، أي بصمة لمحتوى نص برمجي محدد. يجب أن تتطابق قيمة nonce في الترويسة وعنصر النص البرمجي؛ فإدراج قيمة ثابتة في الإعدادات لا يحقق الغرض منها.
ابدأ بسياسة في وضع الإبلاغ ضمن بيئة اختبار، ونفّذ المسار كاملًا من دخول الموقع إلى إرسال نموذج أو إتمام عملية شراء. سيُظهر ذلك الصلاحيات المطلوبة فعليًا قبل أن تبدأ CSP بحظر الموارد لدى المستخدمين.
