فحص رؤوس CORS
تفحص هذه الأداة إعداد رؤوس CORS التي تتحكم في وصول المتصفح بين الأصول. ألصقوا مجموعة رؤوس الاستجابة للتأكد من وجود Access-Control-Allow-Origin، وكشف الجمع غير الآمن بين الأصل العام وبيانات الاعتماد، وتحديد غياب Vary: Origin عند السماح بأصل محدد.
شغّل الأداة مجانًا
النتيجة حتمية وتشرح كل ملاحظة، ولذلك تصلح لمراجعة النشر والتحقيق في الحوادث والفحوص الآلية والتحصين الدوري لواجهات API، من دون إرسال أي طلب إلى الخادم المستهدف.
اقرؤوا النتيجة بوصفها مراجعة محددة النطاق
ابدؤوا بنسخ رؤوس الاستجابة كما استلمها المتصفح أو عميل سطر الأوامر تماماً، مع كتابة زوج واحد بالصيغة اسم: قيمة في كل سطر. تُقارن أسماء الرؤوس من دون اعتبار لحالة الأحرف، وتُعامل قيم Vary المفصولة بفواصل كعناصر مستقلة. تشترط الأداة وجود Access-Control-Allow-Origin لأنه لا توجد سياسة استجابة CORS قابلة للتقييم من دون هذا الرأس؛ لذلك يؤدي غيابه إلى خطأ في الإدخال بدلاً من تقرير غير حاسم. يعرض التقرير الناجح الأصل المسموح به بعد توحيده، وما إذا كانت بيانات الاعتماد مفعلة، وما إذا كانت الاستجابة تتغير تبعاً لـ Origin، وقائمة مرتبة بالملاحظات. يعني الحقل valid عدم اكتشاف مشكلة بدرجة خطأ، لكن قد يبقى تحذير؛ لذا ينبغي للأنظمة المستهلكة فحص issue_count وissues أيضاً. هذا النطاق الضيق مقصود، فهو يقدم حقائق ثابتة عن خطأين شائعين من دون الادعاء بأن نموذج التفويض الكامل للتطبيق آمن. احتفظوا بالاستجابة الأصلية وأصل الطلب مع النتيجة عندما يكون الفحص جزءاً من سجل تدقيق.
افهموا الأصل العام والطلبات المصحوبة ببيانات اعتماد
يكون Access-Control-Allow-Origin: * مناسباً للموارد العامة حقاً التي لا تستخدم بيانات اعتماد، لأنه يتيح لأي أصل طالب قراءة الاستجابة. ولا يجوز جمعه مع Access-Control-Allow-Credentials: true. ترفض المتصفحات هذا الجمع في وصول CORS المصحوب ببيانات اعتماد، وغالباً ما يكشف الإعداد أن الخادم لم يعبّر بصورة صحيحة عن حدود الثقة المقصودة. تسجل الأداة هذه الحالة باسم wildcard_origin_with_credentials وبدرجة خطأ. ولا يكون العلاج بعكس كل قيمة Origin واردة تلقائياً. حددوا الأصول الموثوقة، وقارنوا Origin الخاص بالطلب بقائمة سماح صريحة، ثم أعيدوا أصلاً واحداً معتمداً بعد التطابق فقط. إذا لم تكن ملفات تعريف الارتباط أو بيانات الاعتماد المحيطة ضرورية، فعطلوا دعم بيانات الاعتماد وأبقوا سياسة الأصل العام. وتذكروا أن CORS يتحكم في قدرة نصوص المتصفح على قراءة الاستجابة؛ فهو ليس مصادقة أو تفويضاً أو حماية من تزوير الطلبات أو جداراً نارياً. راجعوا سمات ملفات تعريف الارتباط وضوابط التفويض والأساليب والرؤوس المكشوفة وسلوك الطلبات التمهيدية بصورة مستقلة.
استخدموا Vary: Origin لضبط الذاكرات المخبئية المشتركة
عندما يختار الخادم قيمة محددة لـ Access-Control-Allow-Origin وفق Origin الوارد في الطلب، يصبح تمثيل الاستجابة معتمداً فعلياً على ذلك الرأس. يخبر Vary: Origin المتصفحات والوكلاء العكسيين وشبكات توزيع المحتوى بأن الاستجابات المعدة لأصول مختلفة ليست قابلة للتبادل. وفي غيابه قد تعيد الذاكرة المخبئية استخدام استجابة تحمل الأصل المسموح به لمستأجر واحد مع طلب آخر، مما يسبب أعطالاً متقطعة وقد يضعف افتراضات السياسة المتعلقة بالمحتوى المخزن. لذلك تصدر الأداة missing_vary_origin عندما يكون الأصل المسموح محدداً ولا يتضمن Vary كلاً من Origin أو الرمز العام. وتتعرف على Origin داخل سطر Vary مفصول بفواصل وعبر رؤوس Vary المتكررة. تبقى الملاحظة تحذيراً لأن الاستجابة الملصقة لا تكشف ما إذا كانت قيمة الأصل ثابتة لكل الطلبات أو كان التخزين المؤقت معطلاً في موضع آخر. تحققوا من منطق الاختيار الفعلي للخادم ومن توجيهات التخزين قبل تغيير بيئة الإنتاج. وإذا كان الأصل يُعكس ديناميكياً بعد التحقق منه في قائمة سماح، فإن إضافة Origin إلى Vary تكون عادة أوضح إشارة للذاكرة المخبئية وأكثرها أماناً.
حالات الاستخدام
مراجعة نشر واجهة API
ألصقوا رؤوس استجابة من بيئة الاختبار واكتشفوا إعدادات بيانات الاعتماد أو تنويع الذاكرة المخبئية غير الآمنة قبل الإصدار.
التحقيق في أعطال CORS بالمتصفح
حولوا الرؤوس الملتقطة إلى ملاحظات صريحة عندما تختلف واجهة المستخدم باختلاف الأصل أو مسار الذاكرة المخبئية.
أتمتة فحوص الإعداد
مرروا مجموعات رؤوس حتمية إلى API ضمن CI، وأوقفوا فحص السياسة عند ظهور ملاحظة بدرجة خطأ.
الأسئلة الشائعة
ما تكلفة الفحص؟
يعمل إصدار المتصفح محلياً، وتبلغ تكلفة كل طلب API مقدار $0.002.
لماذا يعد غياب Access-Control-Allow-Origin خطأ؟
هذا الرأس هو أساس سياسة استجابة CORS. ومن دونه لا توجد قيمة أصل مسموح بها تستطيع هذه الأداة المحددة تقييمها.
هل يكون Access-Control-Allow-Origin: * غير آمن دائماً؟
لا. فهو مناسب لبعض الموارد العامة التي لا تسمح ببيانات الاعتماد. ويتطلب الخطأ وجود الأصل العام وضبط بيانات الاعتماد على true معاً.
لماذا يعد غياب Vary: Origin تحذيراً لا خطأ؟
لا تكشف الاستجابة وحدها ما إذا كان الأصل يتغير بين الطلبات أو كان وسيط يستطيع تخزينها. ويدعو التحذير إلى التحقق من هذا السياق.
هل يثبت هذا الفحص أن نقطة النهاية آمنة؟
لا. إنه يفحص خطأين شائعين في رؤوس CORS. وتحتاج المصادقة والتفويض وسياسة ملفات تعريف الارتباط والطلبات التمهيدية والأساليب المسموحة والحماية من التزوير إلى مراجعة مستقلة.
هل تراعي أسماء الرؤوس حالة الأحرف؟
لا. تُقارن أسماء رؤوس HTTP وعناصر التوجيه المعنية من دون تمييز بين الأحرف الكبيرة والصغيرة.
للمطوّرين — الوصول عبر API
كل ما في هذه الصفحة متاح برمجيًا. هذا القسم موجّه للفرق التقنية التي تريد ربط الأداة بأنظمتها الخاصة؛ بقية المستخدمين يمكنهم استخدام الأداة أعلاه مباشرة دون الحاجة لقراءة ما يلي.
الـEndpoint
صادِق على طلبك بترويسة Bearer، وأرسل طلب POST واحدًا لتدخل مهمتك قائمة التنفيذ فورًا؛ ثم تستلم النتيجة عبر webhook أو رابط موقّع.
استدعِ الخدمة من بيئتك
curl -X POST https://api.kit.forhosting.com/security/cors-header-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"headers":"Access-Control-Allow-Origin: https://app.example.com\nAccess-Control-Allow-Credentials: true\nVary: Accept-Encoding, Origin"}'const res = await fetch("https://api.kit.forhosting.com/security/cors-header-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"headers": "Access-Control-Allow-Origin: https://app.example.com\nAccess-Control-Allow-Credentials: true\nVary: Accept-Encoding, Origin"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/security/cors-header-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"headers": "Access-Control-Allow-Origin: https://app.example.com\nAccess-Control-Allow-Credentials: true\nVary: Accept-Encoding, Origin"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/security/cors-header-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"headers":"Access-Control-Allow-Origin: https://app.example.com\\nAccess-Control-Allow-Credentials: true\\nVary: Accept-Encoding, Origin"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"headers":"Access-Control-Allow-Origin: https://app.example.com\nAccess-Control-Allow-Credentials: true\nVary: Accept-Encoding, Origin"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/security/cors-header-check", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)مثال على الطلب
{
"headers": "Access-Control-Allow-Origin: https://app.example.com\nAccess-Control-Allow-Credentials: true\nVary: Accept-Encoding, Origin"
}مثال على الاستجابة
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "security.cors_header_check",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}الواجهة غير متزامنة: تستلم task_id فور الإرسال، ويمكنك الاستعلام عن الحالة بمعدل طلب واحد في الثانية.
الأسعار
السعر معلن كما تراه: لا tokens ولا نظام نقاط؛ وإن فشلت المهمة فلن تُحاسَب عليها.
الأخطاء
| HTTP | الرمز | المعنى |
|---|---|---|
401 | unauthorized | مفتاح الوصول مفقود أو غير صالح؛ تحقق من ترويسة Bearer في طلبك. |
402 | insufficient_balance | رصيدك لا يكفي لتنفيذ هذه المهمة؛ أعد شحن الرصيد ثم أعد المحاولة. |
404 | unknown_type | نوع المهمة المطلوب غير موجود في الكتالوج — راجع الاسم المرسل في الطلب. |
429 | rate_limited | تجاوزت الحد المسموح من الطلبات؛ انتظر قليلًا ثم أعد المحاولة. |