> EXECUTE: EXERCISE_2_DEVSECOPS.SH

DevSecOps

В современном быстро развивающемся ландшафте разработки программного обеспечения важно интегрировать безопасность на каждом этапе жизненного цикла разработки. DevSecOps, сочетающий в себе разработку, безопасность и эксплуатацию, подчеркивает важность внедрения практик безопасности в рабочий процесс DevOps для обеспечения безопасной и качественной доставки программного обеспечения.

PyGoat — это уязвимое веб-приложение на Python, которое мы используем в этой практике.

1. Предварительные требования

2. Создайте форк репозитория и настройте секреты

Dockerhub Username Secret Dockerhub Password Secret

3. Создание базового пайплайна

name: CI

on: [push]

jobs:
  sast_scan:
    name: Run Bandit Scan
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.8'

      - name: Install Bandit
        run: pip install bandit

      - name: Run Bandit Scan
        run: bandit -ll -ii -r . -f json -o bandit-report.json

      - name: Upload Artifact
        uses: actions/upload-artifact@v6
        if: always()
        with:
          name: bandit-findings.json
          path: bandit-report.json

  image_scan:
    name: Build and Run Image Scan
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Fix Docker DNS
        run: |
          echo '{"dns": ["8.8.8.8", "1.1.1.1"]}' | sudo tee /etc/docker/daemon.json
          sudo systemctl restart docker

      - name: Build Docker Image
        run: docker build -f Dockerfile -t mytestapp:latest .

      - name: Docker Scout Scan
        uses: docker/scout-action@v1.15.1
        with:
          dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }}
          dockerhub-password: ${{ secrets.DOCKERHUB_PASSWORD }}
          command: quickview,cves
          only-severities: critical,high
          sarif-file: scout-report.sarif
          exit-code: true

      - name: Upload Artifact
        uses: actions/upload-artifact@v6
        if: always()
        with:
          name: docker-scout-findings
          path: scout-report.sarif

Примечание:

  • Рабочий процесс предварительно настроен на SAST-сканирование с помощью Bandit и сканирование образов Docker с использованием Docker Scout.
  • Каждое задание запускается на стандартном раннере GitHub ubuntu-latest.
  • Рабочий процесс аутентифицируется в Docker Hub с использованием секретов. Вам необходимо добавить учетные данные DockerHub в репозиторий, используя секреты GitHub (DOCKERHUB_USERNAME и DOCKERHUB_PASSWORD).

Убедитесь, что рабочий процесс запустился после отправки изменений (push). Статус «Failed» ❌ (Ошибка) ожидаем. В данном случае это означает, что в приложении были обнаружены уязвимости.

Workflow Result Scout Findings

Разверните результаты сканирования, чтобы просмотреть обнаруженные уязвимости. Вы также можете скачать отчеты о сканировании.

DAST

Создайте новое задание под названием dast_scan. Задание развернет приложение, а затем использует ZAP (или Nikto, как в примере кода) для сканирования его на наличие уязвимостей.

Отредактируйте ваш файл рабочего процесса и добавьте в него следующий текст. Будьте внимательны с отступами. Скопируйте текст в точности так, как есть, со всеми пробелами.

ВНИМАНИЕ: Не перезаписывайте ранее созданные задания. Это дополнение к тому, что мы создали ранее.

  dast_scan:
    name: Deploy and Run DAST Scan with Nikto
    runs-on: ubuntu-latest

    steps:
      - name: Checkout My Repository
        uses: actions/checkout@v6

      - name: Install System Dependencies and Nikto
        run: |
          sudo apt-get update
          sudo apt-get install -y libjpeg-dev zlib1g-dev libpq-dev python3-dev nikto

      - name: Set up Python for DAST
        uses: actions/setup-python@v6
        with:
          python-version: '3.12'

      - name: Install Python Requirements
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Apply Migrations
        run: python3 manage.py migrate

      - name: Run Server
        run: nohup python3 manage.py runserver 0.0.0.0:8000 &

      - name: Wait for Server to Start
        run: sleep 10

      - name: Check Server Availability
        run: curl -I http://127.0.0.1:8000

      - name: Run Nikto Scan
        run: |
          nikto -h http://127.0.0.1:8000 -o nikto-report.html -Format html || true

      - name: Verify Nikto Report File
        run: ls -la

      - name: Upload Artifact
        uses: actions/upload-artifact@v6
        if: always()
        with:
          name: nikto-report
          path: nikto-report.html
DAST Scan Result Scan Report Download

Полный пайплайн (GitHub Actions)

Примечание: представленный выше код и интерфейс относятся к системе GitHub Actions.

Вы можете ознакомиться с полным итоговым вариантом пайплайна, открыв файл конфигурации по ссылке ниже:

CI pipeline run completed successfully
main.yml triggered by push
sast_scan
1m 12s
image_scan
2m 45s
dast_scan
3m 05s
Исходный код main.yml

Альтернатива: GitLab CI/CD

Если вы используете GitLab вместо GitHub, конфигурация пайплайна будет описываться в файле .gitlab-ci.yml. Ниже представлен пример эквивалентного пайплайна для GitLab:

Passed
Pipeline #123456789 triggered by push
just now
sast
image_scan
dast
stages:
  - sast
  - image_scan
  - dast

sast_scan:
  stage: sast
  image: python:3.8
  script:
    - pip install bandit
    - bandit -ll -ii -r . -f json -o bandit-report.json
  artifacts:
    paths:
      - bandit-report.json
    when: always

image_scan:
  stage: image_scan
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  script:
    - docker build -f Dockerfile -t mytestapp:latest .
    - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image mytestapp:latest > trivy-report.txt
  artifacts:
    paths:
      - trivy-report.txt
    when: always

dast_scan:
  stage: dast
  image: python:3.12
  script:
    - apt-get update && apt-get install -y nikto
    - pip install -r requirements.txt
    - python3 manage.py migrate
    - nohup python3 manage.py runserver 0.0.0.0:8000 &
    - sleep 10
    - nikto -h http://127.0.0.1:8000 -o nikto-report.html -Format html || true
  artifacts:
    paths:
      - nikto-report.html
    when: always

Дополнительное задание