الامتثال والحوكمة ونضج DevSecOps

لوحات الأمان وإدارة الثغرات

4 دقيقة للقراءة

الرؤية هي أساس الأمان. بدون لوحات مركزية وإدارة منهجية للثغرات، تغرق فرق الأمان في التنبيهات بينما تفلت المشاكل الحرجة. هذا الدرس يغطي بناء رؤية أمنية فعالة عبر خط أنابيب DevSecOps.

هندسة الرؤية الأمنية

┌─────────────────────────────────────────────────────────┐
│              طبقة الرؤية الأمنية                         │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐       │
│  │  SAST   │ │   SCA   │ │  DAST   │ │ فحص    │       │
│  │ النتائج │ │ النتائج │ │ النتائج │ │الحاويات │       │
│  └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘       │
│       │           │           │           │             │
│       └───────────┴───────────┴───────────┘             │
│                       │                                  │
│                       ▼                                  │
│           ┌───────────────────────┐                     │
│           │    طبقة التجميع      │                     │
│           │  (DefectDojo, ASPM)   │                     │
│           └───────────┬───────────┘                     │
│                       │                                  │
│           ┌───────────┴───────────┐                     │
│           │                       │                     │
│           ▼                       ▼                     │
│    ┌─────────────┐        ┌─────────────┐              │
│    │  اللوحة    │        │  التنبيهات  │              │
│    │ (Grafana)   │        │ (PagerDuty) │              │
│    └─────────────┘        └─────────────┘              │
│                                                          │
└─────────────────────────────────────────────────────────┘

DefectDojo: منصة إدارة الثغرات

التثبيت

# نشر Docker Compose
git clone https://github.com/DefectDojo/django-DefectDojo.git
cd django-DefectDojo

# بدء DefectDojo
docker-compose up -d

استيراد نتائج الفحص

# الاستيراد عبر API
curl -X POST "https://defectdojo.example.com/api/v2/import-scan/" \
  -H "Authorization: Token $DEFECTDOJO_TOKEN" \
  -H "Content-Type: multipart/form-data" \
  -F "scan_type=Trivy Scan" \
  -F "file=@trivy-results.json" \
  -F "product_name=MyApp" \
  -F "engagement_name=CI/CD Pipeline"

تكامل GitHub Actions

# .github/workflows/security-scan.yml
name: Security Scan & Report

on:
  push:
    branches: [main]

jobs:
  scan-and-report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Trivy Scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          format: 'json'
          output: 'trivy-results.json'

      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: auto
          output: semgrep-results.json

      - name: Upload to DefectDojo
        run: |
          # رفع نتائج Trivy
          curl -X POST "${{ secrets.DEFECTDOJO_URL }}/api/v2/import-scan/" \
            -H "Authorization: Token ${{ secrets.DEFECTDOJO_TOKEN }}" \
            -F "scan_type=Trivy Scan" \
            -F "file=@trivy-results.json" \
            -F "product_name=${{ github.repository }}" \
            -F "engagement_name=Pipeline-${{ github.run_id }}" \
            -F "close_old_findings=true"

          # رفع نتائج Semgrep
          curl -X POST "${{ secrets.DEFECTDOJO_URL }}/api/v2/import-scan/" \
            -H "Authorization: Token ${{ secrets.DEFECTDOJO_TOKEN }}" \
            -F "scan_type=Semgrep JSON Report" \
            -F "file=@semgrep-results.json" \
            -F "product_name=${{ github.repository }}" \
            -F "engagement_name=Pipeline-${{ github.run_id }}"

بناء لوحات الأمان بـ Grafana

جمع المقاييس مع Prometheus

# prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'security-metrics'
    static_configs:
      - targets: ['security-exporter:9090']

مصدّر مقاييس الأمان

# security_exporter.py
from prometheus_client import start_http_server, Gauge
import requests
import time

# تعريف المقاييس
VULNERABILITIES_TOTAL = Gauge(
    'security_vulnerabilities_total',
    'إجمالي الثغرات حسب الخطورة',
    ['severity', 'product']
)

SLA_COMPLIANCE = Gauge(
    'security_sla_compliance_percentage',
    'نسبة الثغرات ضمن SLA',
    ['product']
)

MTTR = Gauge(
    'security_mttr_days',
    'متوسط وقت الإصلاح بالأيام',
    ['severity', 'product']
)

def collect_metrics():
    # جلب من DefectDojo API
    response = requests.get(
        f"{DEFECTDOJO_URL}/api/v2/findings/",
        headers={"Authorization": f"Token {DEFECTDOJO_TOKEN}"},
        params={"active": "true"}
    )

    findings = response.json()['results']

    # العد حسب الخطورة
    severity_counts = {}
    for finding in findings:
        severity = finding['severity']
        product = finding['product_name']
        key = (severity, product)
        severity_counts[key] = severity_counts.get(key, 0) + 1

    for (severity, product), count in severity_counts.items():
        VULNERABILITIES_TOTAL.labels(
            severity=severity,
            product=product
        ).set(count)

if __name__ == '__main__':
    start_http_server(9090)
    while True:
        collect_metrics()
        time.sleep(60)

JSON لوحة Grafana

{
  "dashboard": {
    "title": "نظرة عامة على الأمان",
    "panels": [
      {
        "title": "الثغرات الحرجة",
        "type": "stat",
        "targets": [{
          "expr": "sum(security_vulnerabilities_total{severity='Critical'})"
        }],
        "fieldConfig": {
          "defaults": {
            "thresholds": {
              "steps": [
                {"color": "green", "value": 0},
                {"color": "yellow", "value": 1},
                {"color": "red", "value": 5}
              ]
            }
          }
        }
      },
      {
        "title": "اتجاه الثغرات",
        "type": "timeseries",
        "targets": [{
          "expr": "sum(security_vulnerabilities_total) by (severity)",
          "legendFormat": "{{severity}}"
        }]
      },
      {
        "title": "MTTR حسب الخطورة",
        "type": "bargauge",
        "targets": [{
          "expr": "security_mttr_days",
          "legendFormat": "{{severity}}"
        }]
      }
    ]
  }
}

إدارة SLA للثغرات

تعريف SLAs

الخطورة من الاكتشاف إلى الفرز من الفرز إلى الإصلاح
حرج 4 ساعات 24 ساعة
عالي 24 ساعة 7 أيام
متوسط 3 أيام 30 يوم
منخفض 7 أيام 90 يوم

سير عمل تتبع SLA

# .github/workflows/sla-check.yml
name: SLA Compliance Check

on:
  schedule:
    - cron: '0 9 * * *'  # يومياً الساعة 9 صباحاً

jobs:
  check-sla:
    runs-on: ubuntu-latest
    steps:
      - name: Check SLA Breaches
        uses: actions/github-script@v7
        with:
          script: |
            const response = await fetch(
              `${process.env.DEFECTDOJO_URL}/api/v2/findings/?active=true`,
              {
                headers: {
                  'Authorization': `Token ${process.env.DEFECTDOJO_TOKEN}`
                }
              }
            );

            const data = await response.json();
            const now = new Date();

            const slaLimits = {
              'Critical': 1,   // يوم واحد
              'High': 7,       // 7 أيام
              'Medium': 30,    // 30 يوم
              'Low': 90        // 90 يوم
            };

            const breaches = data.results.filter(finding => {
              const created = new Date(finding.created);
              const daysOpen = (now - created) / (1000 * 60 * 60 * 24);
              return daysOpen > slaLimits[finding.severity];
            });

            if (breaches.length > 0) {
              console.log(`SLA Breaches: ${breaches.length}`);
              breaches.forEach(b => {
                console.log(`- ${b.title} (${b.severity})`);
              });

              // إنشاء issue أو إرسال تنبيه
              await github.rest.issues.create({
                owner: context.repo.owner,
                repo: context.repo.repo,
                title: `Security SLA Breach Alert: ${breaches.length} findings`,
                body: breaches.map(b => `- ${b.title} (${b.severity})`).join('\n'),
                labels: ['security', 'sla-breach']
              });
            }
        env:
          DEFECTDOJO_URL: ${{ secrets.DEFECTDOJO_URL }}
          DEFECTDOJO_TOKEN: ${{ secrets.DEFECTDOJO_TOKEN }}

تكوين التنبيهات

تكامل PagerDuty

# alertmanager.yml
route:
  receiver: 'security-team'
  routes:
    - match:
        severity: critical
      receiver: 'security-critical'
      continue: true

receivers:
  - name: 'security-team'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/xxx'
        channel: '#security-alerts'
        title: '{{ .CommonAnnotations.summary }}'

  - name: 'security-critical'
    pagerduty_configs:
      - routing_key: 'your-pagerduty-key'
        severity: critical

تنسيق تنبيه Slack

# قالب التنبيه
- name: Security Vulnerability Alert
  run: |
    curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
      -H 'Content-type: application/json' \
      -d '{
        "blocks": [
          {
            "type": "header",
            "text": {
              "type": "plain_text",
              "text": "🚨 تم اكتشاف ثغرة حرجة"
            }
          },
          {
            "type": "section",
            "fields": [
              {"type": "mrkdwn", "text": "*الخطورة:*\nحرجة"},
              {"type": "mrkdwn", "text": "*المستودع:*\n${{ github.repository }}"},
              {"type": "mrkdwn", "text": "*CVE:*\nCVE-2024-XXXXX"},
              {"type": "mrkdwn", "text": "*SLA:*\n24 ساعة"}
            ]
          },
          {
            "type": "actions",
            "elements": [
              {
                "type": "button",
                "text": {"type": "plain_text", "text": "عرض التفاصيل"},
                "url": "https://defectdojo.example.com/finding/123"
              }
            ]
          }
        ]
      }'

مقاييس الأمان الرئيسية

المقياس الوصف الهدف
MTTR متوسط وقت الإصلاح حرج < 24 ساعة
MTTD متوسط وقت الاكتشاف < يوم واحد
كثافة الثغرات الثغرات لكل 1000 سطر كود < 1.0
امتثال SLA النسبة ضمن SLA > 95%
معدل الإيجابيات الخاطئة النتائج غير الصالحة < 10%
التغطية نسبة المستودعات المفحوصة 100%

بعد ذلك، سنستكشف نموذج نضج DevSecOps وبناء ثقافة الأمان أولاً. :::

اختبار

الوحدة 6: الامتثال والحوكمة ونضج DevSecOps

خذ الاختبار