Всем привет!

Меня зовут Роман, я — DevOps-инженер компании Nixys. Продолжаем тему безопасности и рисков. В предыдущей статье говорилось о безопасном подходе к эксплуатации облачных инфраструктур, в этой — расскажу про безопасность docker-образов: какие уязвимости бывают, как их искать в энтих самых docker-образах (спойлер: использовать сканеры уязвимостей, обзор прилагается) и что с ними делать.

Прежде чем начать, приглашаю вас подписаться на наш блог Хабр, TG-канал DevOps FM и познакомиться с YouTube — мы всегда рады новым друзьям :)



Введение


Почему Docker стал таким популярным инструментом? Потому что он ощутимо облегчил нам, айтишникам, жизнь. Стандартизация и простота развертывания –> оптимизация разработки и тестирования –> повышение эффективности и производительности. Я думаю, большинство из читающих эту статью работает с Docker и понимает плюсы и минусы, поэтому подробности здесь излишни.

Оценил удобство и бизнес. Docker обеспечил уровень абстракции, который позволил упаковывать и развертывать приложения одинаково в различных средах, будь то личная машина разработчика или виртуальная машина в облаке – это сократило time-to-market. А ещё — Docker облегчил масштабирование и позволил сократить затраты на инфраструктуру, т.к. появилась возможность запускать несколько контейнеров (приложений) без вреда друг для друга на одном хосте.

Теперь — ближе к делу, точнее к нашим уязвимостям.

Часть 1. Какие уязвимости бывают, какие риски они несут?


Условно уязвимости в docker-образах можно разделить на следующие:
  • OS Vulnerabilities – уязвимости базового образа и системных пакетов, включённых в этот образ;
  • Dependencies – уязвимости в сторонних зависимостях;
  • Software Vulnerabilities – уязвимости непосредственно в коде приложений, которые запускаются в контейнерах;
  • Dockerfile – небезопасные инструкции для сборки образа.

Использование уязвимого docker-образа может представлять значительные риски для безопасности и стабильности IT-инфраструктуры и приложений организации:
  • нарушение безопасности контура инфраструктуры: уязвимый образ может стать для злоумышленников точкой входа для получения несанкционированного доступа к другим контейнерам или даже к хост-системе, к другим внутренним ресурсам организации, конфиденциальным данным…
  • заражение вредоносным ПО: в скомпрометированный образ злоумышленник может подкинуть вредоносное ПО, которое будет заражает инфраструктуру или приложения организации. Это может привести к потере данных или нарушению работы критически важных сервисов;
  • общая нестабильность: использование уязвимого образа может привести к проблемам с производительностью системы.

Чтобы не быть голословным, приведу реальный пример из практики (конечно, опуская некоторые подробности).
  1. Злоумышленники, воспользовавшись уязвимостью в Microsoft Exchange Server, добыли из почтового ящика пароль от административной панели bitrix для dev-сайта, который был переслан обычным plain-text,. Делать так, конечно же, не надо. Устанавливайте пароль на архив с паролями и отправляйте его по другому каналу.


  2. В административной панели bitrix есть инструмент «командная php-строка», с помощью которой можно выполнять любой php-код. Воспользовавшись этим и задействовав внешний VPS сервер для получения reverse shell, был получен доступ к системе внутри контейнера.
  3. После чего злоумышленники провели атаку на повышение привилегий, использовав уязвимость cve-2022-0847 в ядре linux (уязвимы версии, начиная с 5.8 и до 5.16.11, 5.15.25, и 5.10.102), и получили root-доступ в контейнере. Подробнее про данную уязвимость можно почитать тут, тут и тут.
  4. В контейнере были запущены apache и php, требовавшие определенные capabilities для работы, в частности, cap_dac_read_search и cap_dac_override. Использовав их для выхода из контейнера, злоумышленники сумели получить доступ к диску хоста. Подробнее об этом эксплойте можно узнать тут и тут.
  5. На хост-машине хранились бэкапы prod-сайта, включая хеши административных учетных записей в формате md5.salt, далее был произведен оффлайн брут, и повтор пунктов 2-5 в prod-окружении…
  6. ???
  7. ПРОФИТ!!!

К счастью, «злоумышленниками» оказались пентестеры… Будьте внимательны к хранимым sensitive-данным!



Часть 2. Где хранится информация об известных уязвимостях?


Существует несколько типов баз уязвимостей:
  • официальная база уязвимостей CVE (Common Vulnerabilities and Exposures) – это база данных, которая содержит записи об известных уязвимостях в различных программных продуктах. Она поддерживается организацией MITRE Corporation и является стандартом отрасли;
  • базы уязвимостей от производителей – многие производители программного обеспечения поддерживают свои базы уязвимостей, в которых содержатся информация об уязвимостях, найденных в их продуктах. Например, Microsoft имеет базу уязвимостей Microsoft Security Response Center (MSRC), а Oracle – базу уязвимостей Oracle Critical Patch Update;
  • базы уязвимостей от сторонних организаций – существуют сторонние организации, которые поддерживают свои базы уязвимостей. Они часто специализируются на конкретных областях, таких как безопасность мобильных устройств или безопасность Интернета вещей (National Vulnerability Database (NVD), SecurityFocus, Secunia и др).

Наиболее популярные базы: CVE, NVD, Exploit-DB, OSVDB (Open Source Vulnerability Database), SecurityFocus и др.

Существует также система оценки серьезности уязвимостей – CVSS (Common Vulnerability Scoring System), которая используется в различных сканерах.

Часть 3. Так как же искать в своих docker-образах эти ваши уязвимости?


Конечно же превратить всех своих сотрудников в пентестеров использовать инструменты, которые называются сканеры уязвимостей!

Такие сканеры помогают выявить уязвимости и предоставляют рекомендации по их устранению, что может сэкономить тонны времени и сил. В нашей компании в качестве хранилища образов мы как правило используем Harbor, который с помощью адаптеров умеет работать с некоторыми сканерами, краткий обзор которых представлен ниже. Это добавляет удобства в построении пайплайнов. К тому же, он умеет выгружать отчет с уязвимостями в универсальном формате (CSV).


Я сразу исключу из обзора следующие инструменты:
  • CSP (Aqua) – enterprise платформа (кому интересно, могут запросить триальную версию);
  • Sysdig Secure – такая же ситуация, только еще и доступ из РФ запрещен;
  • TensorSecurity и ArksecScanner – два китайских сканера с довольно скудной документацией – набор манифестов и команды для деплоя в k8s-кластер, репозитории в Github не поддерживаются – последние коммиты в январе 21 года и апреле 22 года, 5 и 9 звезд соответственно…

Остается четыре сканера. Давайте посмотрим, насколько сложно их настроить и развернуть, а также на результаты сканирования одних и тех же образов. Предварительный сетап – Harbor 2.8.0 c самоподписанным сертификатом (данное уточнение необходимо, потому что у большинства сканеров/адаптеров в таком случае нужно включать опцию работы без валидации сертификата).

Clair


Данный сканер был дефолтным для Harbor до версии 2.1 и его можно было установить флагом –with-clair. Сейчас актуальная версия Harbor 2.8, так что давайте рассмотрим деплой сканера отдельно от самого регистри.

Также есть один существенный нюанс – адаптер совместим только с устаревшим Clair v2, с v4 (актуальным) работать не будет из-за изменений API.

Чтобы не изобретать велосипед, я использовал образы clair-photon и clair-adapter-photon от goharbor. После развертывания нужно подождать какое-то время (примерно 1 ч, может меньше), пока полностью подтянется база уязвимостей.
docker-compose.yaml
version: '2.3'
services:
  clair:
    container_name: clair
    image: goharbor/clair-photon:v1.10.17
    restart: always
    cap_drop:
      - ALL
    cap_add:
      - DAC_OVERRIDE
      - SETGID
      - SETUID
    dns_search: .
    volumes:
      - type: bind
        source: ./clair-config.yaml
        target: /etc/clair/config.yaml
    networks:
      - clair
  clair-adapter:
    container_name: clair-adapter
    image: goharbor/clair-adapter-photon:v1.10.17
    restart: always
    cap_drop:
      - ALL
    cap_add:
      - DAC_OVERRIDE
      - SETGID
      - SETUID
    dns_search: .
    depends_on:
      - clair
    env_file:
      ./clair-adapter-env
    networks:
      - clair
networks:
  clair:
    external:
      name: harbor_harbor

clair-config.yaml
clair:
  database:
    type: pgsql
    options:
      source: postgresql://postgres:root123@postgresql:5432/postgres?sslmode=disable
      cachesize: 16384
  api:
    port: 6060
    healthport: 6061
    timeout: 300s
  updater:
    interval: 12h

clair-adapter-env
SCANNER_LOG_LEVEL=info
SCANNER_CLAIR_URL=http://clair:6060
SCANNER_CLAIR_DATABASE_URL=postgresql://postgres:root123@postgresql:5432/postgres?sslmode=disable
SCANNER_STORE_REDIS_URL=redis://redis:6379/4?idle_timeout_seconds=30
SCANNER_TLS_INSECURE_SKIP_VERIFY=True




Anchore


С начала 2023 Anchore Engine перестал поддерживаться, вместо него предлагается использовать Syft и Grype, однако т.к. последняя версия еще относительно свежа, а для новых инструментов еще нет адаптеров для Harbor, из обзора убирать не буду.
docker-compose.yaml
version: '2.3'
volumes:
  anchore-db-volume:
    external: false
services:
  api:
    image: anchore/anchore-engine:v1.0.0
    depends_on:
      - db
      - catalog
    ports:
      - "8228:8228"
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    environment:
      - ANCHORE_ENDPOINT_HOSTNAME=api
      - ANCHORE_ADMIN_PASSWORD=foobar
      - ANCHORE_DB_HOST=db
      - ANCHORE_DB_PASSWORD=mysecretpassword
    command: ["anchore-manager", "service", "start", "apiext"]
    networks:
      - anchore
  catalog:
    image: anchore/anchore-engine:v1.0.0
    depends_on:
      - db
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    expose:
      - 8228
    environment:
      - ANCHORE_ENDPOINT_HOSTNAME=catalog
      - ANCHORE_ADMIN_PASSWORD=foobar
      - ANCHORE_DB_HOST=db
      - ANCHORE_DB_PASSWORD=mysecretpassword
    command: ["anchore-manager", "service", "start", "catalog"]
    networks:
      - anchore
  queue:
    image: anchore/anchore-engine:v1.0.0
    depends_on:
      - db
      - catalog
    expose:
      - 8228
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    environment:
      - ANCHORE_ENDPOINT_HOSTNAME=queue
      - ANCHORE_ADMIN_PASSWORD=foobar
      - ANCHORE_DB_HOST=db
      - ANCHORE_DB_PASSWORD=mysecretpassword
    command: ["anchore-manager", "service", "start", "simplequeue"]
    networks:
      - anchore
  policy-engine:
    image: anchore/anchore-engine:v1.0.0
    depends_on:
      - db
      - catalog
    expose:
      - 8228
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    environment:
      - ANCHORE_ENDPOINT_HOSTNAME=policy-engine
      - ANCHORE_ADMIN_PASSWORD=foobar
      - ANCHORE_DB_HOST=db
      - ANCHORE_DB_PASSWORD=mysecretpassword
      - ANCHORE_VULNERABILITIES_PROVIDER=grype
    command: ["anchore-manager", "service", "start", "policy_engine"]
    networks:
      - anchore
  analyzer:
    image: anchore/anchore-engine:v1.0.0
    depends_on:
      - db
      - catalog
    expose:
      - 8228
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    environment:
      - ANCHORE_ENDPOINT_HOSTNAME=analyzer
      - ANCHORE_ADMIN_PASSWORD=foobar
      - ANCHORE_DB_HOST=db
      - ANCHORE_DB_PASSWORD=mysecretpassword
    volumes:
      - /analysis_scratch
    command: ["anchore-manager", "service", "start", "analyzer"]
    networks:
      - anchore
  db:
    image: "postgres:9 "
    volumes:
      - anchore-db-volume:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=mysecretpassword
    expose:
      - 5432
    logging:
      driver: "json-file"
      options:
        max-size: 100m
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
    networks:
      - anchore
  adapter:
    image: "anchore/harbor-scanner-adapter:1.0.1"
    restart: always
    cap_drop:
      - ALL
    dns_search: .
    environment:
      - SCANNER_ADAPTER_LISTEN_ADDR=:8081
      - ANCHORE_ENDPOINT=http://api:8228
      - SCANNER_ADAPTER_LOG_LEVEL=info
      - ANCHORE_USERNAME=admin
      - ANCHORE_PASSWORD=foobar
      - SCANNER_ADAPTER_APIKEY=agL5JFIDhM8Z4n5
      - ANCHORE_CLIENT_TIMEOUT_SECONDS=180
      - ANCHORE_FILTER_VENDOR_IGNORED=false
      - SCANNER_ADAPTER_FULL_VULN_DESCRIPTIONS=true
      - SCANNER_ADAPTER_REGISTRY_TLS_VERIFY=false
      - SCANNER_ADAPTER_REGISTRY_VALIDATE_CREDS=false
    networks:
      - anchore
networks:
  anchore:
    external:
      name: harbor_harbor




Trivy


Trivy является дефолтным сканером для Harbor с версии 2.2 и по текущую, его можно установить флагом –with-trivy, для наглядности опишу здесь отдельным компоузом.
docker-compose.yaml
version: '2.3'
services:
  trivy-adapter:
    container_name: trivy-adapter
    image: goharbor/trivy-adapter-photon:v2.8.1
    restart: always
    volumes:
      - type: bind
        source: ./trivy
        target: /home/scanner/.cache/trivy
      - type: bind
        source: ./reports
        target: /home/scanner/.cache/reports
    env_file:
      ./env
    networks:
      - trivy
networks:
  trivy:
    external:
      name: harbor_harbor

env
SCANNER_LOG_LEVEL=info
SCANNER_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30
SCANNER_STORE_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30
SCANNER_STORE_REDIS_NAMESPACE=harbor.scanner.trivy:store
SCANNER_JOB_QUEUE_REDIS_URL=redis://redis:6379/5?idle_timeout_seconds=30
SCANNER_JOB_QUEUE_REDIS_NAMESPACE=harbor.scanner.trivy:job-queue
SCANNER_TRIVY_CACHE_DIR=/home/scanner/.cache/trivy
SCANNER_TRIVY_REPORTS_DIR=/home/scanner/.cache/reports
SCANNER_TRIVY_VULN_TYPE=os,library
SCANNER_TRIVY_SEVERITY=UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
SCANNER_TRIVY_IGNORE_UNFIXED=False
SCANNER_TRIVY_SKIP_UPDATE=False
SCANNER_TRIVY_OFFLINE_SCAN=True
SCANNER_TRIVY_SECURITY_CHECKS=vuln
SCANNER_TRIVY_INSECURE=True
SCANNER_TRIVY_TIMEOUT=5m0s




DoSec


Китайский сканер, есть enterprise-версия. Качаем архив, распаковываем, запускаем установочный скрипт.
docker-compose.yaml
version: '2.3'
services:
  dosec-db-hb:
    container_name: dosec-db-hb
    image: hub.dosec.cn/library/dosec-db-hb:2022-07-07T16.56.50V2.0-20220706
    restart: always
    ports:
      - "5432:5432"
    networks:
      - dosec
  dosec-scannerapp:
    container_name: dosec-scannerapp
    depends_on:
      - dosec-db-hb
    image: hub.dosec.cn/library/dosec-scannerapp:2022-07-19T17.59.23V1.0.1_prod
    ports:
      - "8899:8899"
    restart: always
    networks:
      - dosec
    volumes:
      - /var/log/dosec-scanner:/dosec/log
  dosec-scanner-hb:
    container_name: dosec-scanner-hb
    depends_on:
      - dosec-db-hb
      - dosec-scannerapp
    image: hub.dosec.cn/library/dosec-scanner-hb:2022-07-19T13.04.06V1.3_release
    command: ["-update_cve"]
    restart: always
    networks:
      - dosec
    volumes:
      - /var/log/dosec-scanner:/dosec/log
networks:
  dosec:
    external:
      name: harbor_harbor



Теперь давайте сравним результаты их работы. В качестве подопытных образов будут использоваться ubuntu:focal, debian:stable-slim, и один кастомный (с заведомо большим количеством уязвимостей) образ на базе php:7.4.27-apache-buster.

ubuntu:focal


debian:stable-slim


php:7.4.27-apache-buster


Таким образом лучшие результаты у Trivy и Anchore, но учитывая, что Trivy на данный момент является дефолтным сканером для Harbor, а также простоту его установки, свой выбор я остановил на нём.

Чтобы потестировать Trivy (без всяких интеграций, адаптеров и пр.) достаточно установить его любым из методов, описанных в документации и выполнить команду:

trivy image postgres:9

в ответ вернется табличка с кратким summary, найденными уязвимостями, их описанием и версией, где они были устранены (картинка кликабельна):



Особенности Trivy:
  • хорошая документация с примерами;
  • интеграции с популярными сервисами (Harbor, Gitlab, Github, k8s (trivy-operator) etc.);
  • компактная база, которая обновляется при каждом запуске;
  • есть summary, удобный вывод. Если пакет установлен из репозитория, можно выводить отчет в разных предустановленных форматах (html, xml или кастомных);
  • может сканировать локальные образы и проекты;
  • умеет в сканирование образов в приватных репозиториях и в сканирование кода приложений в git-репозиториях;
  • находит уязвимости двух типов – проблемы сборок ОС и проблемы в зависимостях (по lock-файлам);
  • умеет опционально показывать только те CVE, для которых были фиксы, а также скрывать CVE, добавленные в локальный whitelist (.trivyignore);
  • вывод осуществляется как на экран, так и в json, при этом есть возможность фильтрации уязвимостей по критичности.


Часть 4. Как можно использовать сканирование в CI/CD пайплайнах?


Если говорить об использовании сканера Trivy, то еще одним его плюсом является наличие готовых workflow шаблонов для GitHub Actions, GitLab CI, Bitbucket Pipelines и др. Можно ознакомиться с ними в документации.

Я же здесь приведу пару сценариев из практики с использованием GitLab, Harbor и любого совместимого с ним сканера.
  1. Запуск сканирования, если поменялся какой-нибудь pom.xml, и образ запушился в Harbor. Джоба должна падать, а пайп прерываться (или нет — в таком случае измените allow_failure на true), если появились CVE определенного уровня, например critical и high.
    scan job
    scan-image:
      stage: scan
      image: debian:stable-slim
      script:
        - apt update && apt install curl jq -y
        - "curl -X 'POST' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/projects/'${PROJECT_NAME}'/repositories/'${REPO}'/artifacts/'${TAG}'/scan' -H 'accept: application/json' -H 'Content-Type: application/json'"
        - sleep 90
        - "curl -X 'GET' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/projects/'${PROJECT_NAME}'/repositories/'${REPO}'/artifacts/'${TAG}'?page=1&page_size=10&with_tag=true&with_label=false&with_scan_overview=true&with_signature=false&with_immutable_status=false' -H 'accept: application/json' -H 'X-Accept-Vulnerabilities: application/vnd.security.vulnerability.report; version=1.1, application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0' > report.json"
        - export CRIT_VULN=$(jq '.scan_overview."application/vnd.security.vulnerability.report; version=1.1".summary.summary.Critical' ./report.json)
        - export HIGH_VULN=$(jq '.scan_overview."application/vnd.security.vulnerability.report; version=1.1".summary.summary.High' ./report.json)
        - |-
            export EXPORT_BODY_DATA=$(cat << EOF 
            [{"tags":"${TAG}","repositories":"${REPO}","projects":[${PROJECT_ID}]}]
            EOF
            )
        - "curl -X 'POST' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/export/cve' -H 'accept: application/json' -H 'X-Scan-Data-Type: application/vnd.security.vulnerability.report; version=1.1' -H 'Content-Type: application/json' -d "${EXPORT_BODY_DATA}" -o export_job_id.json"
        - sleep 15
        - export JOB_ID=$(jq '.id' ./export_job_id.json)
        - curl -X 'GET' "https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/export/cve/download/${JOB_ID}?format=CSV" -H 'accept: application/json' -o report.csv
        - if [[ $CRIT_VULN -ne 0 || $HIGH_VULN -ne 0 ]]; then echo "Образ имеет $CRIT_VULN уязвимостей уровня critical и $HIGH_VULN уровня high. Проверьте отчет, скачав его как артефакт пайплайна."; exit 1; fi
      artifacts:
        when: on_failure
        paths:
        - ./report.json
        - ./report.csv
        expire_in: 1 day
      only:
        changes:
          - "**/pom.xml"
      allow_failure: false
    

  2. Ежемесячный запуск сканирования и алерт в Телеграм (использовался alertmanager). Таким образом, когда зависимости не менялись, но в базах появилась новая CVE, нам сообщит об этом алерт.
    scheduled scan job
    scheduled-scan:
      stage: scan
      image: debian:stable-slim
      script:
        - apt update && apt install curl jq -y
        - "curl -s -X 'POST' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/projects/'${PROJECT_NAME}'/repositories/'${REPO}'/artifacts/latest/scan' -H 'accept: application/json' -H 'Content-Type: application/json'"
        - sleep 90
        - "curl -s -X 'GET' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/projects/'${PROJECT_NAME}'/repositories/'${REPO}'/artifacts/latest?page=1&page_size=10&with_tag=true&with_label=false&with_scan_overview=true&with_signature=false&with_immutable_status=false' -H 'accept: application/json' -H 'X-Accept-Vulnerabilities: application/vnd.security.vulnerability.report; version=1.1, application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0' -o report.json"
        - export CRIT_VULN=$(jq '.scan_overview."application/vnd.security.vulnerability.report; version=1.1".summary.summary.Critical' ./report.json)
        - export HIGH_VULN=$(jq '.scan_overview."application/vnd.security.vulnerability.report; version=1.1".summary.summary.High' ./report.json)
        - |-
            export BODY_DATA=$(cat << EOF 
            [{"endsAt":"$(date +"%Y-%m-%dT%T" -d '+10 minutes' -u)","annotations":{"summary":"${PROJECT_NAME}/${REPO}:latest image has $HIGH_VULN high and $CRIT_VULN critical vulnerabilities","description":"Check Harbor: https://${REGISTRY_URL}/harbor/projects/${PROJECT_ID}/repositories/${REPO}"},"labels":{"alertname":"HarborScanResults"}}]
            EOF
            )
        - echo $BODY_DATA
        - |-
            export EXPORT_BODY_DATA=$(cat << EOF 
            [{"tags":"latest","repositories":"${REPO}","projects":[${PROJECT_ID}]}]
            EOF
            )
        - "curl -X 'POST' 'https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/export/cve' -H 'accept: application/json' -H 'X-Scan-Data-Type: application/vnd.security.vulnerability.report; version=1.1' -H 'Content-Type: application/json' -d "${EXPORT_BODY_DATA}" -o export_job_id.json"
        - sleep 15
        - export JOB_ID=$(jq '.id' ./export_job_id.json)
        - curl -X 'GET' "https://'${REGISTRY_USER}':'${REGISTRY_PASS}'@'${REGISTRY_URL}'/api/v2.0/export/cve/download/${JOB_ID}?format=CSV" -H 'accept: application/json' -o report.csv
        - |-
          if [[ $CRIT_VULN -ne 0 || $HIGH_VULN -ne 0 ]]; then 
          echo "Image ${PROJECT_NAME}/${REPO}:latest has vulnerabilities, sending alert..." && 
          curl -X 'POST' --anyauth --user ${BASIC_AITH_USER}:${BASIC_AUTH_PASS}  "https://'${ALERTMANAGER_URL}'/alertmanager/api/v2/alerts" -H 'accept: application/json' -H 'Content-Type: application/json' -d "${BODY_DATA}"; 
          fi
      only:
        variables:
          - $HARBOR_SCAN == "true"
      artifacts:
        paths:
        - ./report.json
        - ./report.csv
        expire_in: 3 days
    


    В остальных джобах необходимо будет задать условие:

    except:
      variables:
        - $HARBOR_SCAN == "true"
    

    чтобы запускалась только запланированное сканирование.

    Далее в проекте GitLab в разделе «CI/CD –> Schedules» просто указываем время запуска, нужную ветку и задаем переменную HARBOR_SCAN=true.


Часть 5. Мы просканировали и у нас все красное нашли несколько уязвимостей, что делать?


В целом vulnerability management это отдельная тема, и в рамках текущей статьи раскрываться не будет. Однако упомяну функции, которые должны выполняться в рамках организованного вами управления уязвимостями:
  • непосредственно сканирование на уязвимости с использованием автоматизированных инструментов;
  • выявление уязвимостей — анализ результатов сканирования и уведомление о них;
  • определение приоритетов уязвимостей — выявление систем и уровней среды, на которые влияет каждая уязвимость, а также предоставление информации о ее серьезности, влиянии и основных причинах;
  • рекомендации по устранению — предоставление руководства и инструкций по устранению уязвимости;
  • исправление уязвимостей;
  • экранирование уязвимостей — в случаях, когда сложно или невозможно устранить уязвимость в ее источнике, некоторые решения (например, Aqua vShields) обеспечивают виртуальное исправление или экранирование, предотвратив само использование уязвимости. К примеру, если уязвимость основана на доступе к определенному файлу, то будет предложен план смягчения последствий, который включает прекращение любого доступа к этому файлу, а затем аудит соответствующих событий.

Часть этих функций берут на себя сканеры, но далеко не всегда предоставленная ими информация достаточна для устранения проблем. Для более основательного подхода к менеджменту уязвимостей существует много комплексных платформенных решений, как платных, так и опенсорсных (DefectDojo, Archery, Faraday).

Заключение


Рост числа кибератак усилил и потребность в безопасности используемых нами технологий.

С точки зрения владельцев бизнеса, поиск уязвимостей крайне важен по нескольким причинам. Прежде всего, он помогает снизить риски, связанные с потенциальными нарушениями безопасности. Киберугрозы могут оказать значительное влияние на репутацию и прибыль компании. Одно такое нарушение может привести к потере данных, простою и дорогостоящим судебным издержкам. Уделив этому моменту должное внимание можно выявить и устранить уязвимости до того, как ими воспользуются хакеры или другие злоумышленники.

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

С точки зрения технической команды сканирование не менее важно. Хоть оно и не решает всех проблем с кибератаками, сканирование является важной частью комплексной стратегии обеспечения безопасности, включающей и другие методы, такие как регулярное обновление ПО, контроль доступа, сегментация сети и др. Применяя совокупность этих мер и сохраняя бдительность в отношении возникающих угроз, организации могут защитить свои приложения и снизить риски, связанные с использованием уязвимых docker-образов.

Спасибо за прочтение, делитесь мыслями в комментариях)

Комментарии (0)