سياسة أمان المحتوى (CSP) دون تعطيل موقعك
لقد سمعت أن سياسة أمان المحتوى (CSP) ضرورية لحماية موقعك من هجمات البرمجة النصية عبر المواقع (XSS) وحقن البيانات. ولكن عندما تحاول إضافتها، يتعطل موقعك: تختفي الصور، تتوقف النصوص البرمجية عن العمل، تختفي الأنماط. يبدو الأمر وكأنه مقايضة بين الأمان والوظائف. لكن الأمر لا يجب أن يكون كذلك.
في هذا الدليل، ستتعلم نهجًا عمليًا خطوة بخطوة لنشر CSP دون تعطيل موقعك. سنغطي التوجيهات الأساسية، وكيفية استخدام nonces و hashes، وكيفية الاختبار بأمان. بحلول النهاية، سيكون لديك CSP فعال يعزز الأمان دون التضحية بتجربة المستخدم.
ما هي CSP ولماذا تعطل المواقع؟
سياسة أمان المحتوى هي معيار أمان للمتصفح يسمح لك بتقييد الموارد (النصوص البرمجية، الأنماط، الصور، الخطوط، إلخ) التي يمكن تحميلها على صفحتك. يتم تسليمها عبر رأس HTTP مثل Content-Security-Policy: default-src 'self'.
تعطل CSP المواقع لأنها تحظر أي مورد لا يتوافق مع سياستك. إذا كان لديك نصوص برمجية مضمّنة، أو نصوص خارجية من شبكات CDN، أو أنماط مضمّنة، فسيتم حظرها ما لم تسمح بها صراحةً. السلوك الافتراضي هو حظر كل شيء غير مسموح به، ولهذا يمكن لسياسة صارمة أن تعطل موقعًا بسرعة.
المفتاح هو البدء بسياسة متساهلة وتشديدها تدريجيًا مع مراقبة الانتهاكات.
توجيهات CSP الأساسية التي تحتاج إلى معرفتها
تستخدم CSP توجيهات للتحكم في أنواع الموارد المختلفة. إليك أكثرها شيوعًا:
- default-src: احتياطي للتوجيهات الأخرى. ابدأ من هنا.
- script-src: يتحكم في مصادر JavaScript.
- style-src: يتحكم في مصادر CSS.
- img-src: يتحكم في مصادر الصور.
- connect-src: يتحكم في AJAX و WebSocket وأهداف fetch.
- font-src: يتحكم في مصادر خطوط الويب.
- frame-src: يتحكم في مصادر iframe.
- report-uri / report-to: أين ترسل تقارير الانتهاكات.
يمكنك تعيين توجيهات متعددة في رأس واحد، مفصولة بفواصل منقوطة. على سبيل المثال:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://images.example.com
يقبل كل توجيه قائمة مصادر مفصولة بمسافات. يمكن أن تكون المصادر كلمات مفتاحية مثل 'self'، 'unsafe-inline'، 'unsafe-eval'، أو عناوين URL، أو nonces/hashes.
خطوة بخطوة: نشر CSP دون تعطيل موقعك
اتبع هذه الخطوات لنشر CSP بأمان.
- ابدأ بسياسة الإبلاغ فقط. استخدم رأس
Content-Security-Policy-Report-Onlyبدلاً من الرأس التنفيذي. يتيح لك هذا رؤية ما سيتم حظره دون حظره فعليًا. - قم بتعيين سياسة متساهلة. ابدأ بشيء مثل
default-src 'self' 'unsafe-inline' 'unsafe-eval' https:للسماح بمعظم الأشياء. هذا يقلل من التعطل. - اجمع تقارير الانتهاكات. قم بتكوين
report-uriإلى نقطة نهاية تسجل الانتهاكات. راجع هذه التقارير لتحديد الموارد المحظورة. - أصلح الانتهاكات. قم بتحديث الكود الخاص بك لتجنب النصوص البرمجية/الأنماط المضمّنة، أو أضف nonces/hashes. انقل الموارد الخارجية إلى النطاقات المسموح بها.
- شدد السياسة تدريجيًا. أزل
'unsafe-inline'و'unsafe-eval'بمجرد إعادة الهيكلة. ضيق النطاقات المسموح بها. - التبديل إلى وضع التنفيذ. بمجرد أن تظهر التقارير عدم وجود حظر غير متوقع، قم بتغيير الرأس إلى
Content-Security-Policy(بدون-Report-Only). - راقب باستمرار. أبقِ نقطة نهاية التقرير نشطة لالتقاط المشكلات الجديدة.
يضمن هذا النهج التدريجي عدم تعطيل موقعك أثناء تحسين الأمان.
استخدام Nonces و Hashes للنصوص البرمجية المضمّنة
النصوص البرمجية المضمّنة سبب شائع لتعطل CSP. بدلاً من السماح بـ 'unsafe-inline'، استخدم nonce (رقم يُستخدم مرة واحدة) أو hash.
نهج Nonce: قم بإنشاء nonce عشوائي لكل طلب، وأضفه إلى رأس CSP الخاص بك، وقم بتضمينه في علامات script الخاصة بك.
Content-Security-Policy: script-src 'nonce-abc123'
<script nonce="abc123">...</script>
نهج Hash: احسب تجزئة SHA لنصك البرمجي المضمّن وأضفها إلى السياسة.
Content-Security-Policy: script-src 'sha256-xyz...'
تعتبر Hashes الأفضل للنصوص البرمجية المضمّنة الثابتة التي لا تتغير كثيرًا. تعتبر Nonces أفضل للمحتوى الديناميكي.
بالنسبة للأنماط، يمكنك أيضًا استخدام nonces أو hashes، ولكن لاحظ أن style-src مع nonces لا يغطي سمات النمط المضمّنة (مثل style="..."). بالنسبة لتلك، تحتاج إلى 'unsafe-inline' أو إعادة الهيكلة إلى فئات.
توجيهات CSP الشائعة وتأثيرها
| التوجيه | ما يتحكم فيه | المصادر الشائعة |
|---|---|---|
| default-src | احتياطي لجميع أنواع الموارد | 'self', https: |
| script-src | مصادر JavaScript | 'self', 'nonce-...', 'sha256-...', https://cdn.com |
| style-src | مصادر CSS | 'self', 'unsafe-inline', 'nonce-...' |
| img-src | مصادر الصور | 'self', data:, https://images.com |
| connect-src | AJAX, WebSocket, fetch | 'self', https://api.com |
| font-src | خطوط الويب | 'self', https://fonts.gstatic.com |
| frame-src | Iframes | 'self', https://youtube.com |
استخدم هذا الجدول كمرجع سريع عند بناء سياستك.
اختبار ومراقبة CSP الخاصة بك
قبل التنفيذ، اختبر بدقة. استخدم أدوات مطوري المتصفح: تبويب Console يعرض انتهاكات CSP كأخطاء. تبويب Network يعرض رأس CSP.
للاختبار الآلي، فكر في أدوات مثل Google's CSP Evaluator (عبر الإنترنت) أو حزمة npm csp_evaluator. تساعد هذه في تحديد السياسات الضعيفة.
قم بإعداد نقطة نهاية تقرير لجمع الانتهاكات في الإنتاج. يمكنك استخدام خدمة مثل Report URI أو بناء نقطة النهاية الخاصة بك التي تسجل إلى ملف أو قاعدة بيانات. حلل التقارير بانتظام لالتقاط المشكلات الجديدة.
تذكر: CSP ليست رصاصة فضية. إنها طبقة واحدة من الدفاع. اجمعها مع التحقق من المدخلات، وترميز المخرجات، وأفضل ممارسات الأمان الأخرى.
الأسئلة الشائعة
ما الفرق بين Content-Security-Policy و Content-Security-Policy-Report-Only؟
الرأس التنفيذي (Content-Security-Policy) يحظر الانتهاكات. رأس الإبلاغ فقط (Content-Security-Policy-Report-Only) يبلغ فقط عن الانتهاكات دون حظر، مما يسمح لك باختبار السياسة بأمان.
هل يمكنني استخدام CSP مع معالجات الأحداث المضمّنة مثل onclick؟
لا، يتم حظر معالجات الأحداث المضمّنة بواسطة CSP ما لم تستخدم 'unsafe-inline' (وهو أمر غير مستحسن) أو تعيد الهيكلة لاستخدام addEventListener. لأمان أفضل، تجنب معالجات الأحداث المضمّنة.
كيف أسمح لـ Google Analytics مع CSP؟
أضف نطاقات Google Analytics إلى توجيهات script-src و connect-src الخاصة بك. على سبيل المثال: script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com. تحقق من وثائق Google للحصول على أحدث المتطلبات.
نشر CSP لا يجب أن يكون عملية مؤلمة. مع نهج تدريجي، يمكنك حماية مستخدميك من XSS والهجمات الأخرى دون تعطيل موقعك. ابدأ بوضع الإبلاغ فقط، وأصلح الانتهاكات، وشدد سياستك بمرور الوقت.
إذا كنت بحاجة إلى تنسيق أو التحقق من ملفات تكوين JSON بسرعة لتقارير CSP الخاصة بك، جرب JSON Formatter الخاص بنا لتجميل وتصحيح بيانات JSON الخاصة بك.