ثلاثة مسارات تقييم مستقلة مقابل الإصدار v0.11.0 — قياس precision/recall التركيبي مقابل الأنماط المعيارية، وفحص DAST واقعي مقابل OWASP Juice Shop، وفحص SAST واقعي مقابل عرض PyGoat لإطار Django ضمن OWASP Top 10. تؤكد المسارات الثلاثة جميعها أن المحرك يكتشف ما يدّعيه، بالكمون الذي ينشره القياس المرجعي، وبالاتساع الذي تحتاجه قواعد الكود الواقعية.
F1 التركيبي
1.000
38 TP / 0 FP / 0 FN عبر 7 فئات كشف
Juice Shop مقابل v0.6.1
+5 CRITICAL
فحص أسرع بنسبة 35 ٪؛ تم الإبلاغ عن كل سطح تسريب إعدادات
PyGoat واقعي
147 نتيجة
12 فئة ثغرة خلال 17 ثانية زمن فعلي
56 حالة اختبار موسومة عبر 7 فئات كشف. تحتوي كل فئة على متغيرات EXPECT_TP (يجب أن يبلّغ عنها المحرك) ومتغيرات EXPECT_TN (شكل آمن؛ يجب أن يتركها المحرك). تتوفر المجموعة في scripts/accuracy/corpus/؛ والحقيقة المرجعية في scripts/accuracy/manifest.json. تربط أداة التشغيل المخرجات بالحالات الموسومة حسب الفئة + جزء العنوان + الملف + سماحية ±6 أسطر، مع مطابقة أقرب TP غير مُطالَب به بحيث لا يمكن أن يُطالَب بـ TP واحد من قِبل عدة مخرجات.
| الفئة | TP | FP | FN | Precision | Recall | F1 |
|---|---|---|---|---|---|---|
| sqli | 5 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| cmdi | 5 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| path_traversal | 5 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| ssrf | 3 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| open_redirect | 3 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| xss | 4 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| secrets | 13 | 0 | 0 | 1.000 | 1.000 | 1.000 |
| OVERALL | 38 | 0 | 0 | 1.000 | 1.000 | 1.000 |
1.000/1.000/1.000 يعني أن fendix لا يفوّت أبدًا هذه الأنماط المعيارية الـ56 المحددة، وليس أنه لا يفوّت أي شيء على الإطلاق. تقيس المجموعة التركيبية الجانب الإيجابي؛ أما انضباط FP الواقعي مقابل juice-shop والأهداف الإنتاجية فيُتابَع بشكل منفصل في tasks/FP_CORPUS.md ضمن مستودع المحرك. ويؤكد المساران 2 و3 أدناه الملاءمة الواقعية.
make build
python3 scripts/accuracy/run.py --python-engine
# Output:
# Running ./bin/fendix scan --code scripts/accuracy/corpus...
# 20 unique findings (40 after exploding affected_endpoints)
#
# CATEGORY TP FP FN TN PREC REC F1
# ----------------------------------------------------------------------
# sqli 5 0 0 3 1.000 1.000 1.000
# cmdi 5 0 0 3 1.000 1.000 1.000
# path_traversal 5 0 0 3 1.000 1.000 1.000
# ssrf 3 0 0 2 1.000 1.000 1.000
# open_redirect 3 0 0 2 1.000 1.000 1.000
# xss 4 0 0 2 1.000 1.000 1.000
# secrets 13 0 0 3 1.000 1.000 1.000
# ----------------------------------------------------------------------
# OVERALL 38 0 0 18 1.000 1.000 1.000أظهرت المجموعة التركيبية، وقمنا بشحن تحسينين فعليين للمحرك + إصلاح كامن واحد للمنسّق، في الجلسة نفسها:
redirect(request.args.get("x"))؛ وكانت الإسنادات متعددة القفزات تُفوَّت بصمت. أما المصارف الستة الأخرى القابلة للوصول (SQLi / SSRF / XSS / cmd-injection / path-traversal) فكانت جميعها تطبّق مرشّح ثابت-مقابل-غير-ثابت من TASK-114/120/121/134؛ وكان open-redirect هو مصرف TASK-114 الأصلي ولم يحصل بطريقة ما على معالجة السلسلة. Recall: 0/3 → 3/3._cmdi_arg_is_dangerous. قبل الإصلاح، كان os.system("echo hello") يطلق HIGH رغم انعدام قابلية الاستغلال (اختار TASK-121 "الإطلاق عند كل استدعاء طرفي"). Precision: 0.833 → 1.000.runWhiteboxScan الآن بحلّ code_path وspec إلى مسارات مطلقة قبل إرسال ScanRequest. يضبط المُولِّد cmd.Dir = engineDir، لذا كان المسار النسبي يُحَل بصمت إلى لا شيء ضمن مجلد العمل للعملية الابنة. يظهر ذلك على شكل إبلاغ fendix عن 0 نتيجة في قواعد الكود الفعلية — وهو تراجع فعلي معطِّل للمستخدم كامن منذ TASK-118.أمر fendix scan --url القياسي مقابل bkimminich/juice-shop:v17.1.1. بدون مصادقة، وبدون --code، وبدون --enable-active — مجرد خط المعالجة الافتراضي للصندوق الأسود مقابل القياس المرجعي الحديث لتطبيقات الويب من OWASP.
| المقياس | خط الأساس v0.6.1 | v0.19.0 (الآن) | Δ |
|---|---|---|---|
| إجمالي النتائج (بعد إزالة التكرار) | 7 | 12 | +5 |
| CRITICAL | 0 | 5 | +5 |
| مدة الفحص | 42 s | 27 s | −35 % |
| نقاط النهاية المفحوصة | 97 | 97 | — |
جميع النتائج الخمس الجديدة من فئة CRITICAL هي اكتشافات لملفات إعدادات مكشوفة تم شحنها في TASK-133 (المرحلة 17d): على macOS .DS_Store؛ ملفات البيئة .env / .env.local / .env.production؛ ومكوّنات مستودع Git الداخلية .git/HEAD / .git/config / .git/index؛ وعلى Apache .htaccess + .htpasswd. CWE-538.
Juice Shop هو تطبيق SPA — فكل رابط غير معروف يعيد 200 مع محتوى index.html. قد تكون النتائج الخمس من فئة CRITICAL استجابات احتياطية لـ SPA بدلًا من تسريبات حرفية لملفات الإعدادات. ومع ذلك يظل هذا مشكلة أمان حقيقية: فإن تطبيق SPA الذي يقدّم محتوى متطابقًا لمسارات الإعدادات المعروفة قابل للاستغلال في تسميم التخزين المؤقت، وإرباك WAF، وإرباك المشغّل أثناء الاستجابة للحوادث. يبلّغ Fendix عنها بشكل صحيح؛ وقد تكون المعالجة "اضبط الخادم لإرجاع 404 لهذه المسارات" بدلًا من "تدوير السر المسرَّب."
JS_PORT=3001 FENDIX_BIN=./bin/fendix bash scripts/benchmark/run-juice-shop.sh
# Output (bench-results/juice-shop/<timestamp>/):
# Fendix benchmark — OWASP Juice Shop
# Fendix version: fendix v0.11.0 (darwin/arm64)
# Target image: bkimminich/juice-shop:v17.1.1
# Scan duration: 27 seconds
# Endpoints: 97
# Total findings: 12
#
# By severity: CRITICAL: 5 HIGH: 0 MEDIUM: 4 LOW: 2 INFO: 1نسخة من adeyosemanputra/pygoat — تطبيق Django مصمَّم ليكون قابلًا للاستغلال في كل فئة من OWASP Top 10. 52 ملف Python بالإضافة إلى أصول JavaScript. الفحص عبر fendix scan --code /tmp/pygoat --python-engine دون مصادقة أو فحص نشط.
إجمالي النتائج
147
1 CRITICAL · 146 HIGH
مدة الفحص
17.1 s
52 ملف Python + أصول JS
الفئات المكتشفة
12
كل فئة من OWASP Top 10 يعلن عنها PyGoat
| الخطورة | فئة الثغرة | أول اكتشاف |
|---|---|---|
| CRITICAL | Unsafe pickle deserialization (RCE) | dockerized_labs/insec_des_lab/main.py:36 |
| HIGH | Unsafe eval() with dynamic arg | introduction/mitre.py:218 |
| HIGH | subprocess(shell=True) | introduction/mitre.py:233 |
| HIGH | Unsafe yaml.load() (RCE) | introduction/lab_code/test.py:23 |
| HIGH | SSRF — dynamic URL | 2 sites (incl. views.py:963) |
| HIGH | innerHTML XSS | introduction/static/js/a9.js:40 |
| HIGH | Open redirect — 9 sites | broken_auth_lab/app.py:107 |
| HIGH | Hardcoded API key / password / JWT | 3 distinct files |
| HIGH × 133 | Vulnerable dependency (certifi, cryptography, django, …) | requirements.txt |
git clone --depth 1 https://github.com/adeyosemanputra/pygoat /tmp/pygoat
./bin/fendix scan --code /tmp/pygoat --python-engine --max-duration 60s
# Output:
# scan complete duration=17.082s total=147 critical=1 high=146 medium=0
#
# By category:
# deps 135 (real CVE-tagged dependencies in requirements.txt)
# injection 9 (SSRF/XSS/eval/subprocess-shell/pickle/yaml/open-redirect)
# secrets 3 (hardcoded API key, password, JWT)