تخطٍّ إلى المحتوى
العودة إلى التوثيق
12البنية المعمارية

البنية المعمارية

سجلات قرارات البنية المعمارية (ADRs) والأساس التصميمي وراء ماسح Fendix الهجين.

نظرة عامة على النظام

Fendix ماسح هجين. اعتبارًا من الإصدار v0.9 (المرحلة 17b)، مسار الفحص الافتراضي عبارة عن ملف Go تنفيذي واحد — تُجرى فحوص الأسرار وثغرات تبعيات CVE داخل العملية؛ ويستدعي Semgrep الملف التنفيذي المضيف إن كان مثبتًا؛ أما محرك whitebox بلغة Python لفحوص المصادقة / الحقن / تحليل AST فهو اختياري عبر --python-engine. ولا يزال عقد الاتصال بين المحركات (JSON مفصول بأسطر، ADR-002 أدناه) ساريًا للإضافات ولمسار Python الاختياري.

architecture
User CLI Command
       |
       v
+----------------------------------+
|            Go Binary             |
|  - CLI (cobra)                   |
|  - HTTP Scanner    (black-box)   |  Sends real HTTP requests
|  - Orchestrator                  |
|  - Correlator                    |
|  - Reporters                     |
|                                  |
|  In-process Go scanners:         |
|  - Secrets         (TASK-115)    |  16 patterns + .env handling
|  - Dep CVE         (TASK-119)    |  govulncheck / pip / npm
|  - Plugin runtime  (TASK-113)    |  NDJSON IPC subprocess
+----------------+-----------------+
                 |
                 | shells out to host binary
                 v
       +-------------------+
       |  semgrep (host)   |  TASK-116 — graceful absence
       +-------------------+
                 |
                 | --python-engine OPT-IN only
                 v
       +-------------------+
       |  Python Engine    |  TASK-118 — no longer bundled
       |  - Spec Parser    |  Requires local python/ tree
       |  - AST Analyzer   |  or FENDIX_ENGINE pointing at one
       |  - Auth checks    |
       +-------------------+

ADR-001: بنية هجينة بلغتي Go و Python

مقبول (المرحلة 0)؛ تطوّر في v0.9 / المرحلة 17b

السياق

يحتاج Fendix إلى قدرتين مختلفتين جوهريًا: فحص HTTP من نوع black-box (تزامن عالٍ، زمن استجابة منخفض، توزيع كملف تنفيذي واحد) والتحليل الساكن من نوع white-box (كُتب أصلًا بلغة Python لأن منظومة أدوات الأمان فيها — Semgrep و Bandit و detect-secrets — كانت متقدمة بعام عن أي مكافئ في Go). ولم تتفوق أي لغة واحدة في كليهما.

القرار (المرحلة 0 — من v0.1 حتى v0.8)

  • Go لواجهة CLI وماسح HTTP والمنسّق والمرتبط ومُصيّر التقارير. يُترجم إلى ملف تنفيذي واحد مع بدائيات تزامن ممتازة.
  • Python لمحرك التحليل الساكن، مضمّن في الملف التنفيذي عبر //go:embed ويُستخرج إلى ~/.fendix/engine/ عند أول تشغيل. يُشغّل كعملية فرعية. يحمل فحوص Semgrep والأسرار وتحليل AST وثغرات تبعيات CVE.
  • الاتصال عبر JSON مفصول بأسطر عبر stdin/stdout (انظر ADR-002 أدناه).

التطور في v0.9 / المرحلة 17b — لم يعد الافتراضي يحمل Python

بعد خمس سنوات أثبت ADR-001 الأصلي جدواه. فقد نضجت منظومة ماسحات Go (govulncheck يوفّر قابلية الوصول عبر رسم استدعاءات الدوال؛ ومعالجة التعبيرات النمطية كافية للأسرار)، وتجاوزت كلفة تضمين Python — حجم التثبيت، وزمن البدء البارد، وأسئلة الدعم «هل لديّ Python 3.9+؟» — الفائدة المرجوة. تنقل المرحلة 17b مسارات الأسرار و Semgrep إلى Go أصيلة ( internal/scanner/secrets/، internal/scanner/semgrep/ يستدعي الملف التنفيذي المضيف)، وتُسقط توزيعة Python المضمّنة من الملف التنفيذي، وتجعل تشغيل whitebox بلغة Python اختياريًا عبر --python-engine. ويُحفظ عقد IPC من ADR-002 للإضافات ولمسار Python الاختياري؛ ولم يتغير أي شيء في شكل البيانات المتبادلة.

  • انخفض البدء البارد الافتراضي إلى ~5.6 مللي ثانية p50 (كان ~7.3 مللي ثانية في v0.8).
  • لا حاجة لمفسّر Python في مسار الفحص الافتراضي — يعمل fendix على الأجهزة التي لا يوجد بها Python مثبتًا.
  • نفس شكل النتيجة عبر الانتقال — SEC-* المعرّفات ودرجات الخطورة والمراجع كلها متطابقة بايتًا ببايت؛ وتستوعب خطوط الإدخال القائمة النتائج الجديدة دون تغيير.

النتائج الإيجابية (لا تزال قائمة)

  • أفضل أداة لكل مهمة — Go للشبكات، وتبقى Python خيارًا للتحليل المعتمد بكثافة على AST
  • توزيع كملف تنفيذي واحد لواجهة CLI (لم تعد Python مضمّنة)
  • يبقى محرك Python الاختياري قابلًا للتشغيل المستقل لأغراض تصحيح الأخطاء
  • فصل واضح للمسؤوليات بين المحركات عبر عقد NDJSON IPC (لا يزال أساسيًا للإضافات)
  • لا يزال بالإمكان اختبار كل محرك بشكل مستقل

المقايضات وإجراءات التخفيف

  • منظومتا لغتين للصيانة (وحدات Go + pip عند تفعيل Python)
  • يضيف بدء عملية Python الفرعية ~18 مللي ثانية للفحوص الاختيارية (مقيس)
  • على المستخدمين الذين اعتمدوا على فحوص المصادقة/الحقن الضمنية بلغة Python إضافة --python-engine + توفير شجرة python
  • عقد IPC موثّق ومختبَر من طرف إلى طرف في CI

ADR-002: عقد IPC بصيغة JSON مفصول بأسطر

مقبول

السياق

يحتاج منسّق Go إلى التواصل مع محرك Python. ويجب أن يكون البروتوكول بسيطًا وقابلًا لتصحيح الأخطاء وقابلًا للبث وموثوقًا.

الخيارات المدروسة: gRPC (معقّد للغاية)، مقبس Unix + JSON-RPC (عبء إدارة المقبس)، JSON مفصول بأسطر عبر stdin/stdout (الأبسط).

مخطط IPC

ScanRequest (Go → Python stdin)

ScanRequest
{
  "mode": "whitebox",
  "spec": "./openapi.yaml",
  "code_path": "./src/",
  "language": "python",
  "checks": ["secrets", "auth", "injection", "semgrep", "deps"],
  "verbose": false
}

Finding (Python → Go stdout، واحدة لكل سطر)

Finding
{
  "id": "SEC-001",
  "title": "Hardcoded API key detected",
  "severity": "CRITICAL",
  "source": "whitebox",
  "category": "secrets",
  "endpoint": "src/config.py:14",
  "evidence": "API_KEY = 'sk-live-abc...' [truncated]",
  "fix": "Move to environment variable. Rotate the exposed key immediately.",
  "references": ["CWE-798"],
  "confidence": "HIGH",
  "line": "src/config.py:14"
}

منهي البث (السطر الأخير)

terminator
{"done": true, "total": 12}

النتائج الإيجابية

  • صفر تبعيات — JSON و stdin/stdout موجودان في كل لغة
  • قابل للبث — تظهر النتائج في Go فور اكتشافها بواسطة Python
  • قابل لتصحيح الأخطاء — مرّره إلى jq أو cat للفحص
  • محرك Python قابل للاختبار بشكل مستقل
  • بلا منافذ شبكية أو مقابس أو إدارة اتصالات

المقايضات وإجراءات التخفيف

  • لا تحقق من المخطط على مستوى البروتوكول (يُخفَّف عبر الاختبارات)
  • لا اتصال ثنائي الاتجاه أثناء الفحص
  • تُقتطع حقول الأدلة إلى 200 حرف كحد أقصى
  • اختبارات العقد من طرف إلى طرف تُجرى في CI

نموذج تسجيل درجة الخطورة

تُسجَّل درجة كل نتيجة بناءً على فئة التأثير وثقة الاكتشاف وما إذا كانت طرق اكتشاف متعددة متفقة (يحصل المصدر المرتبط على مُضاعِف 1.1x).

scoring-model
Score = ImpactBase[category] x ConfidenceMult[confidence] x SourceMult[source]

CRITICAL  >= 9.0    |  ImpactBase:           ConfidenceMult:   SourceMult:
HIGH      >= 7.0    |    auth_bypass: 10.0     HIGH:   1.0      correlated: 1.1
MEDIUM    >= 4.0    |    injection:    9.5     MEDIUM: 0.75     blackbox:   1.0
LOW       >= 1.0    |    secrets:      9.0     LOW:    0.5      whitebox:   0.9
INFO      <  1.0    |    idor:         8.5
                    |    data_exposure: 7.0
                    |    cors:          6.5
                    |    headers:       4.0
                    |    info_disclosure: 2.0