Gymterview
senior

Что такое Supply Chain Security в контексте контейнеров?

Supply Chain Security (безопасность цепочки поставок) — обеспечение целостности и безопасности всех компонентов, участвующих в создании и доставке программного обеспечения: от исходного кода и зависимостей до финального контейнерного образа, развёрнутого в production.

Атаки на цепочку поставок (SolarWinds, Log4Shell, codecov) продемонстрировали, что компрометация одного звена цепочки может затронуть тысячи организаций-потребителей. В контексте контейнеров цепочка поставок включает: базовый образ, пакеты операционной системы, зависимости приложения (Maven/Gradle), инструменты сборки, CI/CD-платформу и реестр образов.

Основные компоненты Supply Chain Security:

1. SBOM (Software Bill of Materials) — перечень всех компонентов:

SBOM — это машинно-читаемый документ, содержащий полный список компонентов программного обеспечения: пакеты ОС, Java-зависимости (Maven/Gradle), их точные версии, лицензии и криптографические хеши. Два основных формата: CycloneDX и SPDX.

Пример
# Генерация SBOM с помощью Trivy (формат CycloneDX)
trivy image --format cyclonedx \
    --output sbom.cdx.json \
    registry.bank.local/banking-service:1.0.0

# Генерация SBOM с помощью Syft (Anchore)
syft registry.bank.local/banking-service:1.0.0 -o spdx-json > sbom.spdx.json

# Сканирование SBOM на уязвимости (отдельно от генерации)
grype sbom:./sbom.cdx.json

SBOM позволяет быстро определить, содержит ли ваш образ уязвимый компонент. Например, при обнаружении новой CVE в Log4j можно за секунды проверить все SBOM и определить, какие именно сервисы затронуты, вместо того чтобы пересканировать каждый образ.

2. Проверка зависимостей на уязвимости:

Пример
<!-- Maven: OWASP Dependency Check Plugin -->
<plugin>
    <groupId>org.owasp</groupId>
    <artifactId>dependency-check-maven</artifactId>
    <version>10.0.3</version>
    <configuration>
        <failBuildOnCVSS>7</failBuildOnCVSS>
        <suppressionFile>dependency-check-suppressions.xml</suppressionFile>
    </configuration>
</plugin>
Пример
# Запуск проверки зависимостей
./mvnw dependency-check:check
Пример
// Gradle
plugins {
    id 'org.owasp.dependencycheck' version '10.0.3'
}

dependencyCheck {
    failBuildOnCVSS = 7.0f
    analyzers {
        nodeEnabled = false
    }
}

Параметр failBuildOnCVSS=7 означает, что сборка будет автоматически провалена при обнаружении зависимости с уязвимостью, имеющей CVSS-балл 7.0 и выше (High и Critical). Файл suppressionFile позволяет задокументировать исключения для ложных срабатываний или принятых рисков.

3. Фиксация версий зависимостей:

Пример
<!-- Использовать конкретные версии, НЕ диапазоны -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.3.0</version> <!-- Конкретная версия -->
</dependency>

<!-- ЗАПРЕЩЕНО в банковских проектах: -->
<version>[3.0,4.0)</version> <!-- Диапазон версий — может подтянуть непроверенное обновление -->
<version>LATEST</version>    <!-- Последняя версия — непредсказуемый результат сборки -->

Диапазоны версий и метатеги (LATEST, RELEASE) создают нереспроизводимые сборки: один и тот же коммит может дать разный результат в зависимости от момента сборки. Это как минимум нарушает аудируемость, а в худшем случае позволяет злоумышленнику внедрить вредоносный пакет через подмену (dependency confusion attack).

4. Верификация артефактов в Docker:

Пример
FROM eclipse-temurin:21-jre-alpine@sha256:a1b2c3d4...  # Pin по digest

# Проверка контрольной суммы скачиваемых файлов
RUN wget https://example.com/tool.tar.gz && \
    echo "expected_sha256  tool.tar.gz" | sha256sum -c - && \
    tar xzf tool.tar.gz

Pin по digest (@sha256:...) гарантирует, что будет использован ровно тот образ, который был протестирован. В отличие от тега, digest нельзя переназначить на другой образ. Проверка контрольной суммы скачиваемых файлов предотвращает использование подменённых артефактов.

5. SLSA (Supply-chain Levels for Software Artifacts):

SLSA (произносится «salsa») — это фреймворк, определяющий уровни зрелости безопасности цепочки поставок:

Уровень Требования Что это даёт
SLSA 1 Процесс сборки документирован Базовая прозрачность
SLSA 2 Сборка выполняется на CI/CD (не локально), подписанная provenance Защита от ручного вмешательства
SLSA 3 CI/CD-система аудитируемая и защищённая от вмешательства Защита от компрометации pipeline
SLSA 4 Двусторонняя проверка изменений, hermetic build (изолированная сборка без доступа к сети) Полная верифицируемость

Для банковских систем рекомендуется стремиться к SLSA 3 как минимум.

6. Provenance (происхождение артефакта):

Provenance — это подписанный документ (attestation), фиксирующий, кто собрал образ, из какого исходного кода, на какой CI/CD-системе и с какими параметрами. Это позволяет проследить полную цепочку от коммита до деплоя.

Пример
# Генерация attestation с помощью cosign
cosign attest --predicate provenance.json \
    --key cosign.key \
    registry.bank.local/banking-service@sha256:abc123...

# Верификация attestation
cosign verify-attestation \
    --key cosign.pub \
    --type slsaprovenance \
    registry.bank.local/banking-service@sha256:abc123...

7. Полный пайплайн supply chain security (GitHub Actions):

Пример
name: Secure Build Pipeline
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write  # Для keyless signing через Fulcio/Sigstore
    steps:
    - uses: actions/checkout@v4

    - name: Dependency Check
      run: ./mvnw dependency-check:check

    - name: Build
      run: ./mvnw clean package -DskipTests

    - name: Build & Push Image
      id: build
      run: |
        docker build -t registry.bank.local/banking-service:${{ github.sha }} .
        docker push registry.bank.local/banking-service:${{ github.sha }}

    - name: Generate SBOM
      uses: anchore/sbom-action@v0
      with:
        image: registry.bank.local/banking-service:${{ github.sha }}
        format: cyclonedx-json
        output-file: sbom.cdx.json

    - name: Scan for vulnerabilities
      run: trivy image --exit-code 1 --severity CRITICAL registry.bank.local/banking-service:${{ github.sha }}

    - name: Sign Image
      run: cosign sign --yes registry.bank.local/banking-service:${{ github.sha }}

    - name: Attach SBOM to Image
      run: cosign attach sbom --sbom sbom.cdx.json registry.bank.local/banking-service:${{ github.sha }}

Этот пайплайн последовательно выполняет все этапы supply chain security: проверку зависимостей, сборку, генерацию SBOM, сканирование на уязвимости, подпись образа и прикрепление SBOM к образу в реестре. Каждый этап — это «ворота безопасности» (security gate), при провале которого пайплайн останавливается.