DevSecOps وأمن سلسلة التوريد

فحص التبعيات وتحليل مكونات البرمجيات

18 دقيقة الدرس 4 من 28

فحص التبعيات وتحليل مكونات البرمجيات

كل تطبيق حديث هو في معظمه كود من طرف ثالث. خدمة Node.js نموذجية تسحب مئات التبعيات غير المباشرة؛ وتطبيق Java Spring Boot يُشحن بالآلاف من ملفات JAR التي لم تطلبها مباشرةً قط. حين ظهرت ثغرة حرجة في إحدى تلك المكتبات — كـ Log4Shell في مكتبة log4j، CVE-2021-44228 — أوقفت أنظمة الإنتاج في شركات حول العالم خلال ساعات من الإفصاح. المؤسسات التي نجت بأقل الأضرار كانت تعرف بالضبط أين تستخدم تلك المكتبة، وتمكنت من إصدار التصحيح في اليوم ذاته. أما من قضى ثلاثة أيام في البحث اليدوي داخل قواعد الكود فقد عاش تجربةً مختلفة تماماً.

تحليل مكونات البرمجيات (SCA) هو انضباط يقوم على حصر مستمر وتحليل وتصحيح المكوّنات مفتوحة المصدر والطرف الثالث التي يعتمد عليها برنامجك. يجيب على أربعة أسئلة بشكل آلي ومدمج مع خط التسليم: ماذا نعتمد؟ ما الثغرات المعروفة في تلك التبعيات؟ هل تراخيصنا تتعارض مع أسلوب توزيعنا للبرمجيات؟ وكم نستغرق في العلاج؟

مشكلة الحجم: يحل سجل npm بوسيط 83 حزمة غير مباشرة لكل تبعية مباشرة. "نحن نستخدم خمس مكتبات فقط" لا ينطبق أبداً على مستوى شجرة التبعيات الكاملة. أدوات SCA تعمل على الشجرة الكاملة المحلولة، ليس فقط ما يظهر في ملف التعريف.

كيف تعمل قواعد بيانات الثغرات

أدوات SCA لا تكتشف الثغرات — بل تُنسّق. تحلّ شجرة تبعياتك إلى قائمة دقيقة من صيغة package-name@version، ثم تبحث عنها في قواعد بيانات متعددة:

  • NVD (قاعدة بيانات الثغرات الوطنية) — تديرها NIST، المصدر الأساسي. كل CVE يصل إليها مع تقييم CVSS ونطاقات الإصدارات المتأثرة.
  • OSV (ثغرات المصدر المفتوح) — تديرها Google، أسرع وأكثر قابلية للقراءة آلياً، تغطي PyPI وnpm وMaven وRubyGems وGo modules وغيرها.
  • GHSA (قاعدة بيانات الاستشارات الأمنية لـ GitHub) — تغذّي Dependabot مباشرةً. غالباً تحتوي على إشعارات قبل NVD بأيام لأن المطوّرين يُنسّقون الإفصاح مباشرة عبر أدوات GitHub الأمنية.
  • Snyk Intel — قاعدة بيانات تجارية مع تحليل إمكانية الاستغلال الفعلية، وتحليل قابلية الوصول، وطلبات المراجعة التصحيحية. مدفوعة لكنها الأعلى دقةً في تقييم مخاطر الاستغلال الحقيقي.

درجة CVSS وحدها مؤشر ضعيف للتصنيف. ثغرة CVSS 9.8 في مكتبة تستخدمها فقط لوظيفة مساعدة بريئة، حيث مسار الكود المعيب غير قابل للوصول، هي أولوية أقل من CVSS 7.0 في مكتبة مصادقة مكشوفة شبكياً. تضيف أدوات SCA التجارية المتقدمة تحليل قابلية الوصول: تتتبع مخطط استدعاء تطبيقك الفعلي وتخبرك إن كانت الدالة المعيبة قابلة للوصول من نقاط دخول تطبيقك.

Dependabot: تحديثات تبعيات آلية على نطاق واسع

يعمل Dependabot من GitHub بنمطين متمايزين كثيراً ما تخلط بينهما الفرق. تنبيهات Dependabot سلبية — تُخطرك حين تحتوي تبعية في فرعك الرئيسي على CVE معروف. تحديثات الأمان في Dependabot نشطة — تفتح تلقائياً طلب مراجعة (PR) بأدنى ترقية لإصدار تعالج الثغرة. تحديثات الإصدار في Dependabot تذهب أبعد: تفتح PRs بجدول منتظم للحفاظ على التبعيات محدّثة بصرف النظر عن CVEs، وهي أفضل استراتيجية طويلة الأمد لأن إبقاء الفجوة صغيرة يجعل كل تحديث منخفض المخاطر.

اضبط Dependabot عبر .github/dependabot.yml في جذر المستودع:

# .github/dependabot.yml version: 2 updates: # NPM / Node - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" day: "monday" time: "06:00" timezone: "UTC" open-pull-requests-limit: 10 groups: # دمج تحديثات minor/patch لأدوات التطوير — تقليل الضجيج dev-dependencies: patterns: - "*" update-types: - "minor" - "patch" dependency-type: "development" ignore: # تثبيت حزمة تحتاج ترحيلاً يدوياً - dependency-name: "webpack" update-types: ["version-update:semver-major"] labels: - "dependencies" - "automated" reviewers: - "platform-team" # صور Docker الأساسية - package-ecosystem: "docker" directory: "/" schedule: interval: "weekly" labels: - "dependencies" - "docker" # GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" labels: - "dependencies" - "ci"
اجمع تحديثات minor وpatch للتبعيات غير المباشرة في PR واحد أسبوعي. مراجعة 47 PR منفصلاً لتحديثات patch هو عمل متكرر مُضنٍ تتجاهله الفرق — تتراكم وتصبح ديناً تقنياً. الدمج يبقي قائمة الانتظار قابلة للإدارة مع الحفاظ على التبعيات محدّثة. احتفظ بـ PRs فردية للتبعيات المباشرة وتغييرات الإصدارات الرئيسية التي تحتاج مراجعة بشرية.

Renovate: قدرة أكبر وتحكم أدق

Renovate (Mend Renovate) هو البديل مفتوح المصدر الذي تفضله معظم المؤسسات الهندسية الكبيرة على Dependabot لمستودعات monorepo المعقدة أو متعددة البيئات. يدعم مدراء حزم أكثر (بما فيها مخططات Helm، ومزوّدي Terraform، وRegex المخصص)، ولديه قواعد auto-merge أكثر ثراءً، ويوفر issue لوحة تبعيات تمنحك نظرة شاملة على جميع التحديثات المعلّقة.

// renovate.json (جذر المستودع) { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:base", ":dependencyDashboard", ":separatePatchReleases", "group:allNonMajor" ], "schedule": ["before 7am on monday"], "prConcurrentLimit": 5, "prHourlyLimit": 2, "automerge": true, "automergeType": "pr", "packageRules": [ { "matchPackagePatterns": ["*"], "matchUpdateTypes": ["patch"], "automerge": true, "automergeSchedule": ["after 10pm every weekday"] }, { "matchPackageNames": ["node"], "matchUpdateTypes": ["major"], "enabled": false }, { "matchDepTypes": ["devDependencies"], "matchUpdateTypes": ["minor", "patch"], "groupName": "dev tool patches" } ], "vulnerabilityAlerts": { "enabled": true, "schedule": ["at any time"], "labels": ["security"] } }

كتلة vulnerabilityAlerts في Renovate بالغة الأهمية: تتجاوز الجدول الزمني العادي وتفتح PRs تصحيح الأمان فوراً، بصرف النظر عن أي حدود للدُفعات أو التزامن. في خط أنابيب مُهيَّأ جيداً، تُدمج هذه PRs تلقائياً بعد نجاح CI، مما يعني أن CVE حرجة يمكن تصحيحها واختبارها ونشرها دون تدخل بشري — في دقائق لا أيام.

تشغيل SCA في CI: Trivy وGrype وSnyk

يتولى Dependabot وRenovate التصحيح. للـتطبيق — حظر البناء عند إدخال ثغرة عالية الخطورة — تحتاج ماسحاً مدمجاً مع CI. ثلاثة أدوات تهيمن على الاستخدام الإنتاجي:

  • Trivy (Aqua Security) — مفتوح المصدر، سريع، يمسح حزم نظام التشغيل وتبعيات اللغات وطبقات الحاويات والبنية التحتية كأكواد والـ SBOMs. لا يحتاج إعداداً للبيئات الشائعة.
  • Grype (Anchore) — مفتوح المصدر، يتكامل مع Syft لإنشاء SBOM. ممتاز لخطوط أنابيب السياسة كأكواد.
  • Snyk — SaaS تجاري بمستوى مجاني، مع تحليل قابلية الوصول وطلبات مراجعة تصحيحية موجّهة للمطوّر. الأفضل لمن لديه ميزانية ويركز على تجربة المطوّر.
# GitHub Actions: فحص SCA باستخدام Trivy على كل PR # .github/workflows/sca.yml name: SCA Scan on: pull_request: push: branches: [main] jobs: trivy-fs-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Trivy filesystem scan (language deps) uses: aquasecurity/trivy-action@master with: scan-type: "fs" scan-ref: "." format: "sarif" output: "trivy-results.sarif" severity: "HIGH,CRITICAL" exit-code: "1" # إيقاف البناء عند HIGH أو CRITICAL ignore-unfixed: true # تجاهل الثغرات بلا إصلاح — تقليل الضجيج vuln-type: "library" # تبعيات اللغات فقط؛ OS تُعالَج بشكل منفصل - name: Upload SARIF to GitHub Security tab uses: github/codeql-action/upload-sarif@v3 if: always() # رفع حتى عند فشل الخطوة السابقة with: sarif_file: "trivy-results.sarif"
مشكلة إنتاجية — ignore-unfixed: true: هذا الخيار يُخفي النتائج التي لا يوجد لها إصدار مُصحَّح. في معظم خطوط الأنابيب الحقيقية هذا صحيح — حظر بناء بسبب CVE غير قابل للإصلاح يُدرّب المطوّرين على تجاهل الماسح. لكن للثغرات CRITICAL التي لا يوجد لها إصلاح بعد، تحتاج لا تزال إلى ضابط تعويضي: قواعد WAF وقت التشغيل، أو تعطيل مسار الكود المعيب، أو قبول المخاطرة وتوثيقها رسمياً. لا تُخفِ أبداً بصمت؛ وثّق دائماً.

نظافة ملفات القفل: أساس إعادة الإنتاج

ملفات القفل (package-lock.json، yarn.lock، Pipfile.lock، poetry.lock، go.sum، Gemfile.lock، pom.xml بإصدارات مثبّتة) ليست اختيارية. هي الدفاع الأساسي ضد فئتين من هجمات سلسلة التوريد:

  • هجمات ارتباك التبعيات — يُنشر مهاجم حزمة ضارة باسم مطابق لحزمة داخلية على سجل عام. بدون نطاق سجل مُثبَّت، قد يحل مدير الحزم النسخة العامة. ملفات القفل تسجّل URL السجل الدقيق وتجزئة السلامة، مما يجعل الحل محدداً.
  • الكتابة المشابهة (Typosquatting) — اسم حزمة ضارة يشبه حزمة شائعة (lodahs مقابل lodash). ملفات القفل تمنع حل الحزمة الخاطئة بالخطأ بعد اكتمال تثبيت صحيح.

قواعد ملفات القفل الحرجة لخطوط الأنابيب الإنتاجية: احرص دائماً على إيداع ملفات القفل؛ استخدم npm ci (لا npm install) في CI — أمر ci يفشل إن كان ملف القفل غير متزامن مع package.json ولا يعدّله أبداً؛ وتحقق من تجزئات السلامة. ملف قفل Node v2/v3 وgo.sum في Go يضمّنان تجزئات sha512 أو sha256 للأرشيفات المحلولة. إن عُبث بحزمة بعد قفلها، فشل فحص التجزئة وقت التثبيت.

SCA Scanning in a CI/CD Pipeline PR / Push Trigger CI Pipeline Build & Test Trivy SCA Scan SARIF Upload HIGH? PASS Deploy Gate passed FAIL Block PR CVE annotated in PR Vuln Databases NVD / OSV GHSA / Snyk Intel hash + version lookup query Dependabot Auto-fix PR opened SCA scan runs on every PR; HIGH/CRITICAL findings block merge; Dependabot auto-opens fix PRs.
يعمل فحص SCA كبوابة لكل طلب مراجعة بينما يقترح Dependabot الإصلاحات باستمرار — حلقتا تغذية راجعة متكاملتان.

السياسة كأكواد: تطبيق مستوى المخاطر المقبول

أعداد CVEs الخام ليست سياسة. الممارسة الناضجة لـ SCA تُحدد معايير قبول صريحة — عادةً في ملف .trivyignore أو سياسة OPA/Rego — وتعامل الاستثناءات على أنها محدودة زمنياً ومراجعة وخاضعة للتدقيق. كحد أدنى، احظر:

  • أي CVE بمستوى CRITICAL مع إصلاح متاح ودرجة CVSS للاستغلال أعلى من 8.0
  • التراخيص غير المتوافقة مع نموذج توزيعك (GPL في منتج مغلق المصدر)
  • الاعتماد المباشر على حزم تخلى عنها مطوّروها أو أرشفوها

استخدم trivy fs . --format cyclonedx --output sbom.json لإصدار SBOM بصيغة CycloneDX جنباً إلى جنب مع تقرير الثغرات — هذا يُغذّي مباشرةً سير عمل SBOM المُغطَّى في الدرس السابع. حين تنكشف ثغرة zero-day، تتيح لك SBOM المحدّثة البحث في بنيتك التحتية بالكامل في ثوانٍ لا أيام.

حدّد SLO لمتوسط وقت التصحيح (MTTP) حسب الخطورة: CRITICAL مع استغلال معروف — تصحيح خلال 24 ساعة. HIGH مع إصلاح متاح — تصحيح خلال 7 أيام. MEDIUM — تصحيح خلال 30 يوماً كجزء من دورة التحديث الاعتيادية. LOW — بأفضل جهد ممكن. هذه الأرقام هي أهداف Google الداخلية (تقريباً) ومعتمدة على نطاق واسع في برامج أمان المؤسسات. تتبع MTTP يمنحك مقياساً يمكن تحسينه فعلاً، بدلاً من نجاح/فشل ثنائي يُخفي البطء المنهجي.