Defaults.Exposed › الإصلاحات › Content-Security-Policy (CSP)
كيف تُصلح Content-Security-Policy (CSP)
سياسة أمن المحتوى قاعدة أمان يمنحها موقعك لمتصفح كل زائر، تُخبره بالضبط بأي شيفرة يُسمح لها بالعمل. بدونها، إذا وصل أي شيء خبيث إلى صفحة ما — عبر مربع تعليقات، أو إضافة مخترَقة، أو سكربت طرف ثالث — فسيشغّله المتصفح بحرّية، بما في ذلك شيفرة تسرق بهدوء أرقام بطاقات عملائك وكلمات مرورهم أثناء كتابتها، والقفل لا يزال يظهر.
الخلاصة لعملك: إذا عُبث بموقعك يوماً، يمكن لشيفرة خبيثة أن تقرأ تفاصيل بطاقات الدفع وتسجيل الدخول لعملائك مباشرة من صفحة الدفع الخاصة بك بينما يبدو كل شيء طبيعياً تماماً — تاركةً إياك أمام عمليات ردّ مبالغ، ومطالبات احتيال، واختراق بيانات يجب الإبلاغ عنه، وإخفاق في الفحص تستخدمه فرق الأمن لدى العملاء الأكبر لتعطيل صفقة أو قتلها.
ماذا قد يكلّفك هذا
- تنزلق شيفرة مخفية إلى إحدى صفحاتك وتنسخ بصمت كل رقم بطاقة وكلمة مرور يُدخِلها عملاؤك عند الدفع، مرسلةً إياها إلى مهاجم بينما يبدو موقعك طبيعياً تماماً — ولا تكتشف الأمر إلا حين تصل شكاوى الاحتيال.
- يزرع محتال نموذج 'ادفع هنا' مزيّفاً على موقعك الحقيقي يلتقط المدفوعات إلى حسابه الخاص؛ يظن العملاء أنهم دفعوا لك، ويلومونك حين لا تصل البضاعة، ويطالبون باستعادة أموالهم.
- يفحص فريق الأمن لدى عميل أكبر موقعك، فيرى أن هذه الحماية الأساسية مُطفأة، فيُعلِّمها — مُعطّلاً العقد أو خاسراً إياك له حتى تثبت أنه أُصلِح.
- يصبح اختراق يُتتبَّع إلى ضمانة قياسية مفقودة حادثاً يجب الإبلاغ عنه: أسئلة جهة تنظيمية، وإشعارات عملاء، وضربة سمعة تكلّف أكثر بكثير من الإصلاح المجاني.
لماذا يهمّ. القفل يثبت أن الاتصال بموقعك خاص، لكنه لا يفعل شيئاً للتحكم في أي شيفرة تعمل بمجرد وصول الزائر إلى الصفحة. وسياسة أمن المحتوى هي الضمانة التي تفعل ذلك — فهي تُخبر المتصفحات بتجاهل أي سكربت لم يأتِ من مصدر تثق به، فلا يمكن تحويل حقل أو إعلان أو إضافة واحدة عُبث بها إلى أداة لسرقة أموال عملائك وبياناتهم. إنه فحص مُقيَّم في بطاقة درجاتك، يستحق نقاطاً حقيقية، وأحد أوائل الأمور التي تبحث عنها مراجعة أمنية احترافية.
ما هذا، بكلمات بسيطة
حين يزور أحدهم موقعك، يُنزِّل متصفحه صفحتك ويشغّل أي شيفرة عليها — السكربتات التي تجعل القوائم تنسدل، والأزرار تعمل، ونماذج الدفع تُرسَل، وما إلى ذلك. وافتراضياً، يثق المتصفح بها جميعاً. وليس لديه أي وسيلة لمعرفة أي شيفرة هي شيفرتك فعلاً وأيّها دسّها شخص آخر.
سياسة أمن المحتوى (التي تُختصَر غالباً إلى CSP) قائمة قصيرة بالقواعد يلحقها موقعك بكل صفحة، تُخبر المتصفح: “شغّل فقط الشيفرة من هذه المصادر التي وافقت عليها، وارفض كل شيء آخر.” إنه الفرق بين ناد ليلي يُدخِل أي أحد وآخر بقائمة ضيوف على الباب.
والسبب في أهمية هذا إلى هذا الحدّ هو أن المواقع يُعبَث بها باستمرار — ليس دائماً باختراق خادمك، بل عبر الأبواب الخلفية التي تتركها معظم المواقع مفتوحة: حقل تعليق، أو مربع بحث، أو إضافة عتيقة، أو سكربت طرف ثالث للإعلانات أو التحليلات، أو أداة دردشة. فإذا حصل مهاجم على سطر واحد من شيفرته على إحدى صفحاتك، يشغّله المتصفح كأنه شيفرتك. ومن هناك يمكنه قراءة كل ما يكتبه عملاؤك — أرقام البطاقات، وكلمات المرور، والعناوين — وإرساله بهدوء إلى مكان آخر. وسياسة أمن المحتوى تغلق ذلك الباب برفض تشغيل أي شيء من مصدر لم توافق عليه.
ما قد يكلّفك هذا
هذا ليس أمراً مجرّداً. فالهجوم الذي تمنعه سياسة أمن المحتوى — شيفرة محقونة في صفحة تسرق البيانات من عملائك أنفسهم — يقف وراء بعض أكبر اختراقات سرقة البطاقات المسجّلة. إليك كيف يجري الأمر عادة لنشاط تجاري عادي:
-
مُسلِّخ صفحة الدفع غير المرئي. يدسّ مهاجم بضعة أسطر من الشيفرة على صفحة الدفع لديك عبر إضافة معرّضة أو سكربت طرف ثالث مخترَق. ويُنسَخ كل رقم بطاقة واسم ورمز CVV يكتبه عملاؤك ويُرسَل إلى المهاجم في الوقت الفعلي. ويبدو موقعك ويعمل بشكل مثالي؛ والقفل موجود. وتكتشف الأمر بعد أسابيع حين يتصل مزوّد الدفع لديك بشأن مجموعة من بلاغات الاحتيال تتتبّع جميعها إلى متجرك. والآن تواجه عمليات ردّ مبالغ، وتدقيقاً أمنياً قسرياً، وفقداناً محتملاً لحقوق معالجة البطاقات، واختراقاً قد تُلزَم قانوناً بالإبلاغ عنه.
-
نموذج الدفع المزيّف. يحقن محتال مربع “ادفع هنا” مقنعاً على موقعك الحقيقي. يُدخِل العملاء تفاصيلهم ثقةً بعلامتك التجارية؛ ويذهب المال والبيانات إلى المهاجم. ويلومك العملاء — وهم محقّون، لأنه حدث على موقعك.
-
العقد المفقود. يُجري فريق الأمن لدى عميل محتمل أكبر مسحاً آلياً لموقعك ضمن العناية الواجبة بالمورّدين. وتظهر سياسة أمن محتوى مفقودة فوراً كثغرة عالية الخطورة. وبالنسبة لمراجِع مشتريات أو أمن، تُقرأ تلك الضمانة المفقودة الواحدة على أنها “هذا المورّد لا يفعل الأساسيات” — فتتعثّر الصفقة بينما يطلبون معالجة، أو تذهب بهدوء إلى منافس اجتاز.
-
الاختراق الذي يجب الإبلاغ عنه. حين يُتتبَّع اختراق بيانات إلى ضمانة مفقودة قياسية ومجانية، يتوقف عن كونه سوء حظ ويبدأ بالظهور كإهمال. وذلك يغيّر أسئلة الجهة التنظيمية، والتزام إشعار العملاء، والتكلفة — الغرامة والضرر بالسمعة معاً، الذي يبقى طويلاً بعد إغلاق الحادث.
-
الإعلان أو الأداة المخترَقة. تحمّل كثير من المواقع شيفرة من جهات خارجية — شبكات إعلانات، خطوط، دردشة دعم، تحليلات. فإذا اخترِق أي منها، تركب الشيفرة الخبيثة مباشرة إلى صفحاتك. وسياسة أمن المحتوى تحدّ من نطاق الانفجار بالسماح فقط بالمصادر الخارجية المحددة التي تثق بها، فلا يصبح اختراق مورّد واحد اختراقك تلقائياً.
ما هو فعلاً (التفصيل)
تُسلَّم سياسة أمن المحتوى كترويسة استجابة HTTP واحدة — سطر يرسله خادم الويب الخاص بك مع كل صفحة. وقيمتها مجموعة من التوجيهات، يُسمّي كلّ منها نوعاً من المحتوى والمصادر المسموح بها له. مثلاً:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self'
بعبارة بسيطة، يقول ذلك: افتراضياً حمّل الأشياء من موقعي فقط؛ وشغّل السكربتات من موقعي فقط؛ ولا تسمح بإضافات قديمة الطراز؛ ولا تدع مواقع أخرى تضمّن موقعي في إطار.
كيف يبدو “الجيد”. لا يبحث فحصنا عن وجود الترويسة فقط — بل يقرأ السياسة توجيهاً بتوجيه ويقيّم مدى قوّتها فعلاً، كما يفعل مراجِع أمني. السياسة القوية:
- تضع خطّ أساس مقيِّداً (
default-src 'self') ولا توسّعه إلا لأطراف ثالثة موثوقة محددة تستخدمها فعلاً. - تتجنّب الثغرات. لا تستخدم
'unsafe-inline'أو'unsafe-eval'للسكربتات، ولا تستخدم مصادر عامة الاستخدام (*) أو مصادر مخطط مجرّد (مثلhttps:) للسكربتات — فهذه تُعيد فعلياً فتح الباب الذي يُفترَض أن تغلقه السياسة. وحيثما تُحتاج السكربتات المضمَّنة فعلاً، تستخدم nonce أو hash بحيث تعمل شيفرتك المعتمدة المحددة فقط. - تُحكِم الإطارات بـ
frame-ancestors 'self'(وهذا يحجب أيضاً هجوم “ضمّن موقعك لخداع عملائك”) وتعطّل الإضافات القديمة بـobject-src 'none'. - هي مفروضة، لا للإبلاغ فقط. ترويسة
Content-Security-Policy-Report-Onlyتراقب فقط؛ وتوفّر حماية معدومة وقت التشغيل. ويمنحها فحصنا جزءاً ضئيلاً من الدرجة ولا يسجّلها أبداً كاجتياز. أنت محمي فقط بمجرد أن تصبح السياسة مفروضة.
السياسة التي توجد لكنها تتّكئ على 'unsafe-inline' أو 'unsafe-eval' أو مصادر عامة الاستخدام ستظلّ تُقيَّم بضعف — لأنها عملياً توفّر حماية حقيقية ضئيلة. الهدف سياسة محكَمة، لا مجرد أي سياسة.
كيفية الإصلاح (مجاناً، ~1–2 ساعة)
سلّم هذا للشخص التقني لديك أو من يدير موقعك — الإصلاح نفسه مجاني تماماً. نحن نتقاضى رسوماً فقط مقابل مراقبة بقائه في مكانه وصحيحاً بمرور الوقت؛ وتفعيله لا يكلّف شيئاً. والسبب في استغراق هذا ساعة أو ساعتين بدلاً من دقائق هو خطوة التجربة الدقيقة التي تمنعه من حجب أجزاء من موقعك بالخطأ.
-
ابدأ بوضع الإبلاغ فقط — لا تفرض بعد. أضِف ترويسة استجابة
Content-Security-Policy-Report-Only. هذا يراقب ويسجّل ما كان سيُحجَب دون حجب أي شيء فعلاً، فيظلّ الموقع الحيّ يعمل بينما تتعلّم ما يعتمد عليه كل صفحة فعلاً. (مهم: الإبلاغ فقط بحدّ ذاته لا يمنح الزوّار حماية — إنه الخطوة الأولى الآمنة فحسب.) -
ابنِ السياسة مما يستخدمه موقعك فعلاً. راجِع التقارير لإيجاد كل مصدر مشروع للسكربتات والأنماط والخطوط والصور — نطاقك أنت، وتحليلاتك، ومزوّد الدفع لديك، ومضيف خطوطك، وأداة دردشتك — وأدرِجها كمصادر مسموح بها. ونقطة بداية متينة هي
default-src 'self'بالإضافة إلى إدخالات صريحة للأطراف الثالثة الموثوقة التي تستخدمها فعلاً. -
تجنّب الثغرات التي تُبطل الهدف كله. ابتعد عن
'unsafe-inline'و'unsafe-eval'للسكربتات، وتجنّب مصادر عامة الاستخدام مثل*ومخططات مجرّدة مثلhttps:للسكربتات — فهذه تُعيد فتح الثغرة بالذات التي يُفترَض أن تغلقها السياسة. وحيثما تكون السكربتات المضمَّنة لا مفرّ منها، استخدم nonce أو hash بحيث تعمل شيفرتك المعتمدة المحددة فقط. -
أحكِم الإطارات والإضافات. أضِف
frame-ancestors 'self'(هذا يوقف أيضاً مواقع أخرى من تضمين موقعك لخداع عملائك، ويُرضي فحص الـ clickjacking ذا الصلة) وobject-src 'none'لحجب الهجمات القائمة على الإضافات القديمة. -
حوّل من الإبلاغ فقط إلى الفرض. بمجرد نظافة التقارير وعمل الموقع، غيّر اسم الترويسة من
Content-Security-Policy-Report-OnlyإلىContent-Security-Policy. هذه هي الخطوة التي تقدّم الحماية فعلاً — فسياسة الإبلاغ فقط بمفردها لا تفعل، ولن تجتاز الفحص.أين تضبط الترويسة يعتمد على منصتك:
- Cloudflare: Rules ← Transform Rules ← Modify Response Header ← اضبط
Content-Security-Policy. (يمكنك استخدام Cloudflare لتجربة الإبلاغ فقط أيضاً.) - Nginx:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" always; - Apache:
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'self';" - IIS (web.config): أضِف ترويسة استجابة HTTP مخصّصة باسم
Content-Security-Policyبالسياسة كقيمة لها. - Google Workspace / Microsoft 365: هذان يشغّلان بريدك، لا موقعك العام، فتُضبَط السياسة حيثما يُستضاف موقعك فعلاً (Cloudflare أو مضيف الويب الخاص بك أعلاه)، لا في لوحة إدارة بريدك.
- Cloudflare: Rules ← Transform Rules ← Modify Response Header ← اضبط
-
أعِد فحص نطاقك للتأكد من أن السياسة تظهر الآن مفعّلة ومفروضة، دون ثغرات إضعاف.
الأخطاء الشائعة
- التوقف عند الإبلاغ فقط. الخطأ الأكثر شيوعاً منفرداً: تُضاف سياسة في وضع الإبلاغ فقط، فينصرف الجميع، ولا يُحمى الموقع فعلاً أبداً. الإبلاغ فقط لا يحجب شيئاً. يجب أن تحوّل إلى الفرض.
- اللجوء إلى
'unsafe-inline'ليجعله “يعمل فحسب”. حين تحجب السياسة سكربتاً مضمَّناً مشروعاً، يكون الإصلاح السريع هو السماح بكل السكربتات المضمَّنة — لكن ذلك يُعيد فتح الثقب بالذات الذي كان يُفترَض أن تغلقه السياسة. استخدم nonce أو hash بدلاً من ذلك. - استخدام مصدر عام الاستخدام.
*مجرّدة (أوhttps:) فيscript-srcتسمح بسكربتات من أي مكان، ما يعني أن السياسة تمنح حماية حقيقية شبه معدومة وستظلّ تُقيَّم بانخفاض. - نسيان مصادر الأطراف الثالثة. فرض سياسة صارمة دون إدراج الخدمات الخارجية المشروعة التي تستخدمها أولاً (التحليلات، الخطوط، أدوات الدفع) قد يُعطّل أجزاءً من موقعك — وهو بالضبط سبب وجود خطوة تجربة الإبلاغ فقط.
- ضبطها على الصفحة الرئيسية فقط. تحتاج السياسة إلى تغطية كل صفحة، خصوصاً صفحات الدفع وتسجيل الدخول والحساب — فتلك هي التي تستحق الهجوم.
- معاملتها كبديل عن القفل. سياسة أمن المحتوى وHTTPS/HSTS تحميان أشياء مختلفة. أنت تريدها جميعاً؛ وواحدة لا تغطّي عن أخرى.
الأسئلة الشائعة
لستُ شخصاً تقنياً — هل يمكنني التعامل مع هذا بنفسي؟
لستَ بحاجة لفهم التفاصيل. هذا إعداد يضيفه من يدير موقعك أو استضافتك، وعلى خدمات مثل Cloudflare يكون موجَّهاً إلى حدّ كبير. سلّمهم قسم 'كيفية الإصلاح' أدناه. إنه مجاني؛ والتحذير الوحيد أنه ينبغي طرحه بعناية في تجربة مراقبة فقط أولاً حتى لا يحجب أجزاءً من موقعك بالخطأ — وهو بالضبط ما تغطّيه الخطوات.
لديّ بالفعل القفل وشهادة SSL — أليس موقعي آمناً؟
القفل يؤمّن تسليم صفحتك؛ ولا يضبط ما يعمل داخلها. إذا انتهى المطاف بشيفرة خبيثة على صفحة يوماً — عبر إضافة مخترَقة، أو إعلان مخترَق، أو حقل محقون — فلن يمنعها القفل من سرقة البيانات. وسياسة أمن المحتوى هي الطبقة التي تحدّ مما يُسمَح بعمله ابتداءً. إنهما يحميان أشياء مختلفة، وأنت تريد كليهما.
هل قد يُعطّل تفعيل هذا موقعي؟
قد يحدث ذلك إن فُعِّل بقوة دفعة واحدة، لأنه قد يحجب سكربتات مشروعة تستخدمها فعلاً. ولهذا فإن النهج المعياري هو البدء بوضع 'الإبلاغ فقط' (report-only) التجريبي الذي يراقب دون حجب، وإصلاح أي شيء يُعلِّمه، ثم فرضه بعد ذلك فقط. بهذه الطريقة يكون آمناً — وخطوة التجربة مدمجة في الإصلاح أدناه.
وضعناه أصلاً في وضع 'الإبلاغ فقط' — هل نحن مغطّون؟
لا، وهذا أكثر شعور زائف بالأمان شيوعاً. وضع الإبلاغ فقط يراقب ويسجّل ما كان سيُحجَب، لكنه لا يحجب شيئاً — فيحصل الزوّار على حماية حقيقية معدومة. إنه الخطوة الأولى الآمنة فحسب. ويمنح فحصنا وضع الإبلاغ فقط جزءاً ضئيلاً من درجة سياسة حقيقية ولن يسجّله كاجتياز. أنت محمي فقط بمجرد التحويل إلى وضع الفرض.
هل يؤثر هذا في درجتنا، أم أنه إرشادي فقط؟
يؤثر في درجتك. فحص سياسة أمن المحتوى مُقيَّم ويستحق حتى 25 نقطة في فئة أمن الويب. والسياسة المفقودة أو الضعيفة تُعلَّم عالية الخطورة وتجرّ درجتك للأسفل — وهي بالضبط نوع الثغرة الذي يسأل عنه استبيان أمني لعميل.
أضاف مطوّرنا سياسة لكن الدرجة لا تزال منخفضة — لماذا؟
قد توجد سياسة وتظلّ ضعيفة. والمذنبون الأكثر شيوعاً هم ثغرات مثل 'unsafe-inline' و'unsafe-eval' للسكربتات، أو مصادر عامة الاستخدام (* مجرّدة)، التي تُعيد فتح الثغرة بالذات التي يُفترَض أن تغلقها السياسة. ويقرأ فحصنا السياسة توجيهاً بتوجيه ويخفض درجة تلك النقاط الضعيفة — فالسياسة التي تسمح بأي شيء تُقيَّم بقليل أفضل من غيابها. والإصلاح هو تشديد قواعد السكربتات باستخدام nonces أو hashes بدلاً من تلك الثغرات.