أنشئ ترويسة Content-Security-Policy من المصادر المسموح بها
تُخبر ترويسة Content-Security-Policy المتصفح بالمواقع التي يجوز أن توفّر النصوص البرمجية والأنماط والصور والخطوط والإطارات وغيرها من الموارد.
شغّل الأداة مجانًا
تعمل هذه الأداة داخل متصفحك — مجانًا، ولا تُرسل بياناتك إلى أي خادم
يحوّل هذا المنشئ صفوف التوجيهات المنظمة إلى قيمة ترويسة واحدة مفصولة على نحو صحيح، ويكشف الأسماء المجهولة والتكرارات والفواصل غير الآمنة والقيم المفقودة. وهو مفيد عندما تُجمّع السياسة بأداة نشر أو شاشة إعداد أو قائمة تحقق أمنية أو قالب تطبيق، وتحتاج إلى نتيجة متوقعة من دون وصل الأجزاء يدويًا أو قبول توجيه أخطئ في كتابته دون قصد.
صِف السياسة في صفوف من التوجيهات
أدخل صفًا لكل توجيه تريد إرساله ضمن السياسة. يحتوي كل صف على اسم التوجيه وقائمة مرتبة من تعبيرات المصدر أو الرموز. فعلى سبيل المثال يبدأ default-src عادةً بالرمز 'self'، بينما قد يضيف script-src مضيف HTTPS محددًا لتوزيع المحتوى. يحوّل المنشئ أسماء التوجيهات إلى أحرف صغيرة، ويحذف المسافات الخارجية من كل مصدر، ويحافظ على ترتيب الصفوف والمصادر، ثم يصل التوجيهات المكتملة بفواصل منقوطة. وهو لا يخترع توجيهات احتياطية ولا يوسّع السياسة خفيةً. وهذا مهم لأن الحذف والسماح يتركان أثرين أمنيين مختلفين. قد يرجع img-src المفقود إلى default-src، بينما قد يسمح حرف بدل إضافي بمواقع أكثر مما قصدتم. تعاملوا مع كل مصدر بوصفه رمز CSP واحدًا، وحافظوا على علامتَي الاقتباس في كلمات مثل 'self' و'none'. لا تستخدموا مخططات مثل data: إلا إذا احتاج إليها التطبيق فعلًا. الناتج هو قيمة الترويسة كاملة وليس اسمها، ولذلك يمكن إسناده مباشرةً إلى Content-Security-Policy في إعداد الخادم أو الحافة.
يكشف التحقق أخطاء بنية السياسة
لا يقبل المنشئ إلا أسماء توجيهات CSP المعروفة، ويبلغ عن خطأ إدخال عند ورود اسم مجهول. وبذلك يكشف الأخطاء الإملائية التي قد يتجاهلها المتصفح، فتظل فئة من الموارد أقل تقييدًا مما هو متوقع. ويرفض التوجيهات المكررة أيضًا لأن الصف الصريح الواحد أسهل في المراجعة ويمنع النتائج المفاجئة. لا تُقبل الفواصل المنقوطة أو الفواصل أو فواصل الأسطر أو المسافات المضمّنة داخل رمز مصدر منفرد، إذ قد تقسّم السياسة المولدة أو تفسدها. تتطلب معظم التوجيهات مصدرًا أو رمزًا واحدًا على الأقل. أما التوجيهان upgrade-insecure-requests وblock-all-mixed-content فلا يحملان قيمة؛ ويتطلبان قائمة مصادر فارغة ويصدران بالاسم وحده. تتحقق الأداة من البنية، ولا تقرر ما إذا كان المضيف جديرًا بالثقة أو ما إذا كانت السياسة توفر الحماية اللازمة لتطبيقكم. كما أنها لا تجلب موقعًا ولا تفحص شيفرة ولا تولد nonce ولا تختبر توافق المتصفحات. راجعوا الصلاحيات مقارنةً بالسلوك الفعلي للتطبيق، وانشروا التغييرات المقيدة مع المراقبة وفي بيئات مرحلية عندما يمكن أن يؤثر العطل في المستخدمين.
انشر النتيجة وافحصها وحافظ عليها
انسخوا القيمة المعادة إلى ترويسة الاستجابة Content-Security-Policy. احتفظوا بها إعدادًا إلى جانب التطبيق بدل توزيع أجزائها بين البرمجيات الوسيطة وقواعد الوكيل والقوالب. تجعل القائمة المركزية الإضافات قابلة للمراجعة، وتمكّن الأنظمة الآلية من إعادة توليد السلسلة ذاتها تمامًا في كل تشغيل. ابدؤوا بـ default-src أساسًا مقصودًا، ثم أضيفوا توجيهات أضيق مثل script-src وstyle-src وimg-src وconnect-src وfont-src وframe-src وobject-src وframe-ancestors عندما يتطلب التطبيق سلوكًا مختلفًا. فضّلوا المضيفين والمخططات الصريحة على أحرف البدل الواسعة. إذا استخدمتم تجزئات أو nonces، فقدّموا رمز CSP الكامل بين علامتَي اقتباس؛ أما إنشاء nonce نفسه فيخص الطبقة التي تعالج كل طلب، لأن هذه القدرة حتمية ولا تولد قيمًا عشوائية. اختبروا الاستجابة المنشورة في أدوات المطور بالمتصفح، وفكروا في بدء التشغيل بوضع الإبلاغ فقط قبل فرض السياسة. قد تكشف تقارير المتصفح تبعيات محظورة، لكن ينبغي أن تؤدي إلى تعديلات دقيقة لا إلى سماح عشوائي. أعيدوا تشغيل المنشئ عند كل تغيير في الإعداد كي يبقى التحقق جزءًا من مسار التسليم. تكلف طلبات API مبلغ $0.002، بينما تستخدم نسخة المتصفح الخوارزمية النقية ذاتها.
حالات الاستخدام
توليد إعداد الخادم
حوّلوا قائمة مراجعة من توجيهات CSP إلى قيمة الترويسة الدقيقة التي يستخدمها إعداد التطبيق أو الوكيل.
التحقق من نموذج النشر
ارفضوا أسماء التوجيهات المكتوبة خطأً ورموز المصادر المشوهة قبل وصول السياسة إلى بيئة الإنتاج.
الحفاظ على ناتج حتمي
أنشئوا نص CSP ثابتًا من إعداد مضبوط الإصدارات للاختبارات والقوالب وأتمتة البنية التحتية.
الأسئلة الشائعة
ما تكلفة الاستخدام؟
يكلف كل طلب API مبلغ $0.002. تعمل نسخة المتصفح محليًا بالخوارزمية الحتمية ذاتها.
هل تختبر الأداة مدى أمان سياستي؟
لا. تتحقق من أسماء التوجيهات وبنية الناتج، لكن عليكم تحديد المصادر التي ينبغي لتطبيقكم الوثوق بها.
هل يجب إبقاء علامات الاقتباس حول الكلمات المفتاحية؟
نعم. أدخلوا كلمات CSP المفتاحية رموزًا كاملة، مثل 'self' و'none' و'unsafe-inline' و'strict-dynamic'.
هل يمكنها توليد nonce؟
لا. يجب أن تكون nonces غير قابلة للتوقع وأن تُنشأ لكل استجابة. مرروا رمز nonce مُعدًا سلفًا وبين علامتَي اقتباس عند تجميع سياسة محددة.
لماذا تُرفض التوجيهات المكررة؟
صف واحد لكل توجيه واضح وأسهل في التدقيق، ويجنبكم الاعتماد على سلوك المتصفح عند تكرار الأسماء.
كيف أضيف upgrade-insecure-requests؟
أضيفوا هذا التوجيه مع قائمة مصادر فارغة، وسيصدر بوصفه توجيهًا بلا قيمة.
للمطوّرين — الوصول عبر API
كل ما في هذه الصفحة متاح برمجيًا. هذا القسم موجّه للفرق التقنية التي تريد ربط الأداة بأنظمتها الخاصة؛ بقية المستخدمين يمكنهم استخدام الأداة أعلاه مباشرة دون الحاجة لقراءة ما يلي.
الـEndpoint
صادِق على طلبك بترويسة Bearer، وأرسل طلب POST واحدًا لتدخل مهمتك قائمة التنفيذ فورًا؛ ثم تستلم النتيجة عبر webhook أو رابط موقّع.
استدعِ الخدمة من بيئتك
curl -X POST https://api.kit.forhosting.com/security/csp-header-build \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"directives":[{"name":"default-src","sources":["'\''self'\''"]},{"name":"script-src","sources":["'\''self'\''","https://cdn.example.com"]},{"name":"img-src","sources":["'\''self'\''","data:"]}]}'const res = await fetch("https://api.kit.forhosting.com/security/csp-header-build", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"directives": [
{
"name": "default-src",
"sources": [
"'self'"
]
},
{
"name": "script-src",
"sources": [
"'self'",
"https://cdn.example.com"
]
},
{
"name": "img-src",
"sources": [
"'self'",
"data:"
]
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/security/csp-header-build",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"directives": [
{
"name": "default-src",
"sources": [
"'self'"
]
},
{
"name": "script-src",
"sources": [
"'self'",
"https://cdn.example.com"
]
},
{
"name": "img-src",
"sources": [
"'self'",
"data:"
]
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/security/csp-header-build", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"directives":[{"name":"default-src","sources":["\'self\'"]},{"name":"script-src","sources":["\'self\'","https://cdn.example.com"]},{"name":"img-src","sources":["\'self\'","data:"]}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"directives":[{"name":"default-src","sources":["'self'"]},{"name":"script-src","sources":["'self'","https://cdn.example.com"]},{"name":"img-src","sources":["'self'","data:"]}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/security/csp-header-build", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)مثال على الطلب
{
"directives": [
{
"name": "default-src",
"sources": [
"'self'"
]
},
{
"name": "script-src",
"sources": [
"'self'",
"https://cdn.example.com"
]
},
{
"name": "img-src",
"sources": [
"'self'",
"data:"
]
}
]
}مثال على الاستجابة
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "security.csp_header_build",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}الواجهة غير متزامنة: تستلم task_id فور الإرسال، ويمكنك الاستعلام عن الحالة بمعدل طلب واحد في الثانية.
الأسعار
السعر معلن كما تراه: لا tokens ولا نظام نقاط؛ وإن فشلت المهمة فلن تُحاسَب عليها.
الأخطاء
| HTTP | الرمز | المعنى |
|---|---|---|
401 | unauthorized | مفتاح الوصول مفقود أو غير صالح؛ تحقق من ترويسة Bearer في طلبك. |
402 | insufficient_balance | رصيدك لا يكفي لتنفيذ هذه المهمة؛ أعد شحن الرصيد ثم أعد المحاولة. |
404 | unknown_type | نوع المهمة المطلوب غير موجود في الكتالوج — راجع الاسم المرسل في الطلب. |
429 | rate_limited | تجاوزت الحد المسموح من الطلبات؛ انتظر قليلًا ثم أعد المحاولة. |