مستوى المقال: متوسط. يفترض إنك تعرف تبني صورة Docker وتشغّل GitHub Actions، لكن لسه ما أضفتش فحص ثغرات آلي لخط الـ CI.
في آخر هذا المقال هيبقى عندك بوابة أمان تلقائية توقف الـ build وتمنع أي صورة فيها ثغرة حرجة من الوصول للإنتاج، بأقل من 15 سطر YAML.
افحص صور Docker بـ Trivy قبل ما توصل الإنتاج
الرقم اللي يخليك تقرأ: حسب تقرير Sysdig لسنة 2024، 86% من الأحمال في الإنتاج فيها ثغرة قابلة للترقيع من مستوى عالٍ أو أعلى. يعني الاحتمال الأكبر إن الصورة اللي بتنشرها دلوقتي فيها CVE معروف انت مش شايفه.
المشكلة باختصار
صورتك مش بس الكود اللي كتبته. هي كمان نظام تشغيل أساسي (زي debian أو alpine) وعشرات المكتبات اللي جت مع npm install أو pip install. أي حزمة فيهم ممكن يكون فيها ثغرة متسجّلة بمعرّف CVE.
المثال الأشهر: ثغرة Log4Shell (CVE-2021-44228) في مكتبة Log4j. سطر واحد في سجلّ عادي كان بيسمح بتنفيذ كود عن بُعد على السيرفر. ملايين الصور اللي كانت شغّالة عادي بقت مكشوفة بين ليلة وضحاها، من غير ما يتغيّر سطر واحد في كودهم.
يعني إيه فحص الثغرات؟ الفكرة بمثال
تخيّل بوّاب مطار بيقارن كل حقيبة بقائمة أشياء ممنوعة محدّثة يوميًا. مش بيخمّن، وبيفتّش بالظبط جوّه الشنطة ويطابق محتواها مع القائمة. لو لقى حاجة ممنوعة، بيوقف الراكب عند البوابة، مش بعد ما يركب الطيارة.
الآن بالتفاصيل والدقة: Trivy (من Aqua Security) بيعمل نفس الدور للصورة. بيفكّك طبقاتها، بيطلّع قائمة كل حزمة وإصدارها (اللي بتتسمّى SBOM)، وبيطابقها مع قواعد بيانات ثغرات عامة زي NVD. لو حزمة عندك إصدارها مذكور في CVE معروف، Trivy بيبلّغك بمستوى الخطورة: LOW أو MEDIUM أو HIGH أو CRITICAL.
الحل: بوابة فحص في خط الـ CI
الفكرة إن الفحص يشتغل تلقائيًا على كل push، والأهم: يوقف الـ build لو لقى ثغرة خطيرة. ده اللي بيحوّل الفحص من تقرير بيتجاهله الكل إلى بوابة فعلية.
الأول جرّبه محليًا على جهازك قبل ما تدفع:
# افحص صورة محليًا، ورجّع كود خطأ لو فيه ثغرة حرجة أو عالية
trivy image --severity CRITICAL,HIGH --ignore-unfixed --exit-code 1 myapp:1.5.0
وبعدين حطّه في GitHub Actions كبوابة على كل Pull Request:
name: security-scan
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan with Trivy
uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: myapp:${{ github.sha }}
severity: CRITICAL,HIGH
ignore-unfixed: true
vuln-type: os,library
exit-code: '1' # يفشّل الـ build لو لقى ثغرة