DevSecOps سطح: متوسط

Pipeline کامل DevSecOps با Gitleaks، SonarQube، Trivy، ZAP و DefectDojo

امنیت را از انتهای پروژه به داخل Pipeline بیاورید: اسکن Secret، SAST، اسکن وابستگی‌ها و Image، DAST روی محیط تست و تجمیع همه‌ی نتایج در DefectDojo.

۵ دقیقه مطالعه

در بیشتر سازمان‌ها تست امنیت هنوز یعنی یک «تست نفوذ» در هفته‌ی آخر قبل از انتشار. نتیجه هم همیشه همان است: ده‌ها آسیب‌پذیری، فرصت کم و انتخاب بین «انتشار با ریسک» و «تأخیر». DevSecOps یعنی همین بررسی‌ها را به داخل Pipeline بیاوریم تا هر مشکل در همان Merge Request که ایجادش کرده پیدا شود.

با پیاده‌سازی همین لایه‌ها در Pipelineهای یکی از تیم‌ها، تعداد آسیب‌پذیری‌هایی که به Production می‌رسید حدود ۶۰٪ کاهش پیدا کرد.

لایه‌های امنیت در Pipeline

لایه چه چیزی را پیدا می‌کند ابزار زمان اجرا
Secret Detection رمز، Token و کلید API در کد Gitleaks ثانیه
SAST باگ‌های امنیتی در سورس (Injection، XSS و…) SonarQube ۱ تا ۵ دقیقه
SCA کتابخانه‌های آسیب‌پذیر Trivy fs کمتر از ۱ دقیقه
Image Scan CVE در سیستم‌عامل و پکیج‌های Image Trivy image کمتر از ۱ دقیقه
DAST آسیب‌پذیری در برنامه‌ی در حال اجرا OWASP ZAP ۵ تا ۱۵ دقیقه
Mobile مشکلات امنیتی APK و IPA MobSF چند دقیقه

۱. Gitleaks: قبل از هر چیز

secrets:
  stage: .pre
  image: { name: zricethezav/gitleaks:v8.18.4, entrypoint: [""] }
  script:
    - gitleaks detect --source . --redact --report-format json --report-path gitleaks.json
  artifacts:
    when: always
    paths: [gitleaks.json]

۲. SonarQube: کیفیت و امنیت کد

sonarqube:
  stage: test
  image: { name: sonarsource/sonar-scanner-cli:latest, entrypoint: [""] }
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"     # full history for accurate new-code detection
  cache:
    key: sonar
    paths: [.sonar/cache]
  script:
    - sonar-scanner
        -Dsonar.projectKey=$CI_PROJECT_PATH_SLUG
        -Dsonar.host.url=$SONAR_HOST_URL
        -Dsonar.token=$SONAR_TOKEN
        -Dsonar.qualitygate.wait=true
  allow_failure: false

sonar.qualitygate.wait=true باعث می‌شود Job منتظر نتیجه‌ی Quality Gate بماند و اگر رد شد، Pipeline هم شکست بخورد.

۳. Trivy: وابستگی‌ها و Image

dependency-scan:
  stage: test
  image: { name: aquasec/trivy:0.56.2, entrypoint: [""] }
  script:
    - trivy fs --scanners vuln --severity HIGH,CRITICAL --exit-code 0
        --format json --output trivy-fs.json .
  artifacts:
    paths: [trivy-fs.json]

image-scan:
  stage: scan
  image: { name: aquasec/trivy:0.56.2, entrypoint: [""] }
  needs: [docker-image]
  variables:
    TRIVY_USERNAME: $CI_REGISTRY_USER
    TRIVY_PASSWORD: $CI_REGISTRY_PASSWORD
    TRIVY_CACHE_DIR: .trivycache/
  cache:
    paths: [.trivycache/]
  script:
    - trivy image --format json --output trivy-image.json "$IMAGE"
    - trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed "$IMAGE"
  artifacts:
    when: always
    paths: [trivy-image.json]

۴. OWASP ZAP: تست برنامه‌ی در حال اجرا

DAST بعد از استقرار روی Develop اجرا می‌شود و برنامه را مثل یک مهاجم از بیرون بررسی می‌کند:

dast:
  stage: verify
  image: ghcr.io/zaproxy/zaproxy:stable
  needs: [deploy-dev]
  script:
    - mkdir -p /zap/wrk
    - zap-baseline.py -t https://dev.example.ir -J zap.json -r zap.html -I || true
    - cp /zap/wrk/zap.* .
  artifacts:
    when: always
    paths: [zap.json, zap.html]

Baseline Scan حمله‌ی فعال انجام نمی‌دهد و برای اجرا در هر Pipeline امن است. Full Scan را به یک Job شبانه بسپارید. هیچ‌وقت DAST فعال را روی Production اجرا نکنید.

۵. DefectDojo: یک داشبورد برای همه

وقتی پنج ابزار گزارش می‌دهند، تیم امنیت نمی‌تواند پنج داشبورد را دنبال کند. DefectDojo همه‌ی گزارش‌ها را دریافت، موارد تکراری را حذف و وضعیت هر مشکل را از «جدید» تا «رفع‌شده» دنبال می‌کند:

upload-defectdojo:
  stage: .post
  image: curlimages/curl:8.10.1
  when: always
  script:
    - |
      upload() {
        curl -sf -X POST "$DOJO_URL/api/v2/import-scan/" \
          -H "Authorization: Token $DOJO_TOKEN" \
          -F "scan_type=$1" -F "file=@$2" \
          -F "engagement=$DOJO_ENGAGEMENT_ID" \
          -F "close_old_findings=true" -F "active=true" -F "verified=false"
      }
      upload "Gitleaks Scan" gitleaks.json
      upload "Trivy Scan" trivy-image.json
      upload "ZAP Scan" zap.json || true

close_old_findings=true یعنی مشکلاتی که دیگر در اسکن جدید دیده نمی‌شوند، خودکار بسته می‌شوند و داشبورد همیشه وضعیت واقعی را نشان می‌دهد.

سیاست مسدودسازی: چه چیزی Pipeline را متوقف کند؟

یافته اقدام
هر Secret در کد مسدود
Quality Gate سونار روی کد جدید رد شد مسدود
CVE با شدت CRITICAL که Patch دارد مسدود
CVE با شدت HIGH هشدار و ثبت در DefectDojo، رفع در Sprint بعد
یافته‌های ZAP Baseline بازبینی تیم امنیت، بدون مسدودسازی

جمع‌بندی

DevSecOps یعنی امنیت بخش عادی هر Merge Request باشد، نه یک مرحله‌ی جدا در انتهای پروژه. از Gitleaks و Trivy شروع کنید که سریع‌اند و بیشترین ارزش را دارند، بعد SonarQube و ZAP را اضافه کنید و در آخر همه را در DefectDojo جمع کنید.