FreeToGenerate.com

أكثرُ مولّدات CSP تعطيك ترويسةً وتقف. وهذا يجيب عن السؤال المهم: بهذه السياسة، أذلك المسارُ مسموح؟

ما الذي تصنعه هذه السياسةُ حقًّا

  • style-src‏'unsafe-inline' يدع أيَّ سكربتٍ أو نمطٍ محقونٍ يعمل.

أتسمح هذه السياسةُ بمسارٍ ما؟

محجوب

فُحص على script-src

متوفر أيضًا بلغات أخرى: English · Español · Português · Français

مولّد CSP ومدقّقه

اكتب Content-Security-Policy ثم اختبر عليها مسارًا حقيقيًّا، وانظر أيَّ تعابيرِ سياستك لا تصنع شيئًا البتة.

ما Content Security Policy؟

سياسةُ أمن المحتوى ترويسةُ HTTP تخبر المتصفحَ من أين يجوز للصفحة أن تحمّل الأشياء. وهي قائمةُ تعليمات — script-src وimg-src وstyle-src وغيرها — يتبع كلَّ واحدةٍ المصادرُ التي تسمح بها. فإن حاولت الصفحةُ تحميلَ ما لا تسمح به السياسةُ رفض المتصفح.

والمقصودُ تحديدُ الضرر. فإن نجح مهاجمٌ في حقن ترميزٍ في صفحتك، فالسياسةُ الجيدة هي ما يمنع ذلك الترميزَ من تحميل سكربته. وليست CSP بديلًا عن الهروب الصحيح للمخرجات؛ بل هي الطبقةُ التي تحدّ من فداحة العطب حين يخفق الهروب.

وكتابةُ واحدةٍ سهلة. وأما معرفةُ ما كتبتَه حقًّا فليست كذلك، وتلك الفجوةُ ما تحاول هذه الصفحةُ سدَّه. فقواعدُ المطابقة في CSP Level 3 أغربُ مما تبدو، وعدةٌ منها تجعل أجزاءً من السياسة تُهمَل صامتةً: فقد تسرد سياسةٌ عشرةَ مضيفين مسموحين لا أثرَ لهم البتة، ولا شيءَ ينبّهك.

كيف تستعمله؟

  1. ابدأ من قالبٍ أو ألصق سياستك. فالصارمةُ قائمةٌ على nonce وهي ما توصي به الإرشاداتُ الحديثة؛ والمعتادةُ أقربُ إلى ما تحمله أكثرُ المواقع فعلًا. وحرّر النصَّ كما شئت: فكلُّ ما تحته يتحدّث وأنت تكتب.
  2. اقرأ ما تصنعه السياسةُ حقًّا. فاللوحةُ تحتها تسرد الملحوظات: تعابيرَ مهمَلة، وتعليماتٍ ناقصة، ومصادرَ تنقض الحمايةَ التي ظننتها عندك. وكلُّ واحدةٍ قاعدةٌ من المواصفة لا رأي.
  3. ثم اختبر عليها مسارًا حقيقيًّا. اختر نوعَ المورد، وألصق المسارَ الذي تريد تحميله والأصلَ الذي تُقدَّم منه صفحتُك. فتحصل على حكمٍ، وعلى التعليمة التي فُحصت بعد سلسلة الرجوع، وعلى تعبير المصدر الذي حسم الأمر بعينه.

قواعدُ المطابقة التي لا يكاد أحدٌ يعرفها

مطابقةُ المخطط غيرُ متناظرة، وهي فوق ذلك ترفع. فالمواصفةُ تقول إن المخطط http يطابق https، ومعناه أن script-src http://example.com يسمح أيضًا بـhttps://example.com، ولا عكس. فكتابةُ الصورة غير الآمنة تسمح بالاثنتين صامتةً. والقاعدةُ نفسُها تجعل ws يطابق wss وhttp وhttps جميعًا، وهو منحٌ أوسعُ بكثيرٍ مما يقصده أحد.

والمضيفُ بالنجمة لا يشمل النطاقَ نفسَه. فالنمطُ *.example.com يُعالَج بحذف النجمة الأولى واشتراطِ أن ينتهي المضيفُ بـ.example.com، وexample.com لا ينتهي بذلك. فسياسةٌ تسمح بـ*.example.com تحجب example.com، وهو عكسُ ما يظن أكثرُ الناس أنهم كتبوه. ويعني ذلك أيضًا أن نمطَ مضيفٍ لا يطابق عنوان IP قط، لأن الخوارزمية تشترط نطاقًا.

والمساراتُ لا تكون مطابقةَ بادئةٍ إلا إذا انتهت بشرطةٍ مائلة. فبغير شرطةٍ في الآخر تكون المطابقةُ تامّة، فـscript-src https://cdn.example/js يسمح بذلك المسار وحده ولا شيءَ تحته. والمقاطعُ تُفكّ من ترميز النسبة المئوية قبل المقارنة، فالشرطةُ المرمَّزة تبقى مقطعًا واحدًا لا اثنين.

والمنافذُ ترجع إلى الافتراضي. فمصدرٌ بلا منفذٍ يطابق منفذَ المخطط الافتراضي، فـhttps://example.com وhttps://example.com:443 أصلٌ واحد — وهو أيضًا ما يجب أن يعنيه 'self'.

أجزاءُ سياستك التي لا تصنع شيئًا

ثمة قاعدتان تجعلان تعابيرَ موجودةً في السياسة بلا أثرٍ البتة، ولا تُرى واحدةٌ منهما إن لم تعرف أن تبحث عنها.

الأولى 'strict-dynamic'. فإذا ورد في script-src أو default-src قالت المواصفةُ إن مصادرَ المضيف ومصادرَ المخطط، ومعها 'unsafe-inline' و'self'، تُهمَل عند تحميل السكربتات. ولا يبقى معتبَرًا إلا الـnonce والبصمات. وذلك متعمَّدٌ وهو كيفيةُ عمل المنهج الحديث القائم على nonce، لكنه يعني أن سياسةً تقول script-src 'strict-dynamic' 'nonce-abc' https://cdn.example 'self' لا تسمح بشيءٍ من ذلك الـCDN بمضيفه. والمدقّقُ يسرد كلَّ تعبيرٍ أهمله ويقول أيُّ قاعدةٍ أهملته.

والثانية 'unsafe-inline' إلى جانب nonce أو بصمة. فحينئذٍ يُهمَل 'unsafe-inline'، وتلك هي الحيلةُ بعينها لكتابة سياسةٍ تتدرّج بلطفٍ في المتصفحات القديمة: فالتي تفهم الـnonce تطيعه، والتي لا تفهمه ترجع إلى 'unsafe-inline'. نافعٌ حين يكون مقصودًا، مقلقٌ حين يكون عرضًا، فهذه الصفحةُ تفرّق بين الحالين بدل أن تسم 'unsafe-inline' وسمًا واحدًا فيهما.

وثمة فجوةٌ ثالثةٌ هي غيابٌ لا إهمال. فالتعليمات frame-ancestors وform-action وbase-uri لا ترجع إلى default-src. فسياسةُ default-src 'self' لا تقيّد التأطيرَ البتة، ولا تقيّد إلى أين تُرسَل النماذج، وتترك base-uri مفتوحًا، فيستطيع الترميزُ المحقون إعادةَ توجيه كلِّ مسارٍ نسبيٍّ في الصفحة. والمدقّقُ يقول لك صراحةً إنه لا تنطبق أيُّ تعليمة.

حدودٌ صادقة

هذا يفحص مطابقةَ المسارات، وهي جزءُ CSP الذي فيه قواعدُ حقيقيةٌ ومفاجآتُ حقيقية. ولا يحاكي كلَّ ما يصنعه المتصفح. فالسكربتُ والنمطُ في المتن، وeval، والتحويلات، والوراثةُ في العمّال، والصندوقُ الرملي، وTrusted Types، وإرسالُ التقارير، كلُّها خارجَ ما يجيب عنه المدقّق، وسياسةٌ تسمح هنا بمسارٍ قد تحجب الموردَ في متصفحٍ لأحد تلك الأسباب.

والـnonce والبصماتُ تُعرَف ولا تُقيَّم. فكونُ سكربتٍ متنيٍّ بعينه يطابق nonce يتبع الترميزَ لا السياسة، فالمدقّقُ يعاملها تعابيرَ موجودةً دون أن يزعم أنها تُمرّر مسارًا بعينه.

والملحوظاتُ قواعدُ لا درجةُ أمان. فقد تجتاز سياسةٌ كلَّ فحوص هذه الصفحة وتبقى ضعيفة، لأن CSP لا تحمي صفحةً يقدّم أصلُها نفسُه سكربتًا يتحكم فيه المهاجم. ولا شيءَ في هذه الصفحة بديلٌ عن ترميز المخرجات ترميزًا صحيحًا.

ولا توجد مجموعةُ مطابقةٍ لـCSP ولا مطابِقٌ مرجعيٌّ على npm ينفّذ خوارزميات تعابير المصدر، فالمحركُ فُحص على الأمثلة المشروحة في المواصفة نفسِها وعلى خوارزمياتها منقولةً توكيداتٍ مع أرقام أقسامها. وكلُّ قاعدةٍ غيرِ متناظرة تُختبَر في الاتجاهين، لأن مجموعةً تفحص الاتجاهَ المتساهل وحده يرضيها تنفيذٌ يسمح أكثرَ من اللازم — وهو عينُ العطب المهم هنا.

لماذا هو مجاني؟

لأن تشغيله لا يكلّف شيئًا. فالسياسةُ تُحلَّل والمسارُ يُفحص في متصفحك وأنت تكتب؛ لا يُرفع شيء، ولا يُسجَّل شيء، ولا يرى خادومٌ السياسةَ ولا المساراتِ التي تلصقها.

فلا حساب ولا تسجيل ولا شيءَ محجوب. وقواعدُ المطابقة من مواصفة Content Security Policy Level 3 لا من تلخيص موقعٍ آخر لها، والفحوصُ التي تتحقق منها محفوظةٌ إلى جوار الصفحة.