Marker689 c43e7c4c9b fix: критические баги и качество кода — полный аудит
Критические фиксы:
- main.py: монтировать /static из web/static/ (CSS не грузился совсем)
- api/scans.py: filtered total count (был всегда общий, игнорируя фильтры)
- web/routes.py: исправлен VALID_SORT_FIELDS (отсутствовали ключи packages)
- web/routes.py: filtered total count для web scans list
- package_detail.html: f.data.X вместо f.X (findings не отображались)

Чистка мёртвого кода:
- config.py: удалён _parse_repos и nexus_repositories (не использовались)
- web/routes.py: удалён completed_scans/failed_scans (не отображались)
- удалён мёртвый guarddog_nexus/static/style.css (67-байтный стаб)

Качество кода:
- web/routes.py: Jinja2 Environment кэшируется на уровне модуля
- Вынесен дублирующийся JS в web/static/app.js
- Вынесены дублирующиеся inline-стили в CSS-классы
- Исправлен duplicate class attribute в списках
- Удалены гигантские SVG из empty states

Тесты:
- 20 новых edge-case тестов (CSV export, search/filter/sort, 404, pagination)
- Добавлен sample_flagged_scan fixture
- Итого: 50 тестов, все зелёные
2026-05-10 03:46:05 +03:00
2026-05-09 04:32:48 +03:00

GuardDog Nexus

Интеграция [GuardDog](https://github.com/DataDog GuardDog) (сканер уязвимостей пакетов PyPI) с [Sonatype Nexus Repository Manager]. Автоматически сканирует Python-пакеты, хранящиеся в Nexus, на наличие уязвимостей, вредоносного кода и подозрительных паттернов при каждом обновлении или добавлении пакета.

Возможности

  • Автоматическое сканирование по вебхукам Nexus при создании/обновлении пакетов
  • Поддержка нескольких экосистем — PyPI, Gem, и другие форматы через Nexus
  • REST API для просмотра результатов сканирования, уязвимостей и статистики
  • Веб-интерфейс с дашбордом, таблицами сканирований и фильтрацией по уязвимостям
  • Дедупликация по URL и SHA256 — один и тот же пакет сканируется один раз
  • Структурированное логирование в формате JSON с опциональной отправкой в syslog
  • Docker Compose для развёртывания приложения, Nexus и настройки в одном стеке

Архитектура

Nexus ──(webhook)──> GuardDog Nexus ──(REST API)──> Веб-интерфейс
                         │
                         ├──> GuardDog CLI (сканирование)
                         ├──> SQLite (хранилище результатов)
                         └──> REST API (данные для UI)

Быстрый старт

Требования

  • Docker и Docker Compose
  • Python 3.10+ (для локальной разработки)

Развёртывание в Docker

# Скопируйте файл конфигурации
cp .env.example .env

# Отредактируйте .env при необходимости
# NEXUS_PASSWORD=<ваш_пароль_администратора_Nexus>

# Запустите стек
make docker-up

После запуска доступны:

Сервис URL Порт
GuardDog Nexus http://localhost:8080 8080
Sonatype Nexus http://localhost:8081 8081

Локальная разработка

# Установите зависимости
make install dev

# Настройте переменные окружения
cp .env.example .env
export $(cat .env | xargs)

# Запустите приложение
python -m guarddog_nexus.main

Переменные окружения

Переменная По умолчанию Описание
NEXUS_URL http://localhost:8081 URL Sonatype Nexus
NEXUS_USERNAME admin Имя пользователя Nexus
NEXUS_PASSWORD (обязательно) Пароль пользователя Nexus
NEXUS_REPOSITORIES (пусто) Список репозиториев через запятую
DATABASE_PATH data/guarddog.db Путь к SQLite-базе данных
HOST 0.0.0.0 Хост для прослушивания
PORT 8080 Порт для прослушивания
LOG_LEVEL INFO Уровень логирования
LOG_SYSLOG_HOST (пусто) Хост syslog для отправки логов
LOG_SYSLOG_PORT 514 Порт syslog
WEBHOOK_SECRET (пусто) Секрет для HMAC-подписи вебхуков
SCAN_TIMEOUT_SECONDS 300 Таймаут сканирования одного пакета
TEMP_DIR /tmp/guarddog-nexus Временная директория для загрузки пакетов

Настройка Nexus

Создание репозитория

  1. Убедитесь, что в Nexus создан репозиторий pypi-proxy (прокси на https://pypi.org)
  2. Настройте вебхук Nexus для отправки событий на http://<guarddog-nexus>:8080/webhooks/nexus
  3. Используйте scripts/setup-nexus.sh для автоматической настройки (требует curl)

Вебхуки

Nexus отправляет вебхуки при событиях ASSET и COMPONENT. GuardDog Nexus поддерживает:

  • CREATED — новое событие при создании пакета
  • UPDATED — событие при обновлении пакета

Для валидации вебхуков установите WEBHOOK_SECRET — подпись проверяется через HMAC-SHA256.

Примечание: Вебхуки доступны в Nexus Pro. В Nexus Repository Manager 3 Community Edition настройка вебхуков может потребовать дополнительных плагинов.

REST API

Сканирования

Метод Путь Описание
GET /api/v1/scans Список сканирований (пагинация, фильтр flagged)
GET /api/v1/scans/stats Статистика: общее количество, уязвимые пакеты, топ правил
GET /api/v1/scans/{id} Детали конкретного сканирования с результатами

Пакеты

Метод Путь Описание
GET /api/v1/packages Список уникальных пакетов (пагинация, фильтр по экосистеме)
GET /api/v1/packages/{name}/{version} Все сканирования и уязвимости для пакета

Уязвимости

Метод Путь Описание
GET /api/v1/findings Список уязвимостей (фильтр по правилу, severity, scan_id)

Здоровье

Метод Путь Описание
GET /health Проверка работоспособности

Веб-интерфейс

Страница URL Описание
Дашборд / Статистика, графики, топ уязвимых пакетов
Сканирования /scans Таблица всех сканирований с фильтрацией
Детали сканирования /scans/{id} Результаты одного сканирования
Пакеты /packages Таблица уникальных пакетов
Детали пакета /packages/{name}/{version} История сканирований и уязвимости пакета

Структура проекта

guarddog-nexus/
├── guarddog_nexus/           # Основной пакет
│   ├── main.py               # Точка входа FastAPI
│   ├── config.py             # Конфигурация из переменных окружения
│   ├── database.py           # Async SQLAlchemy + aiosqlite
│   ├── models.py             # ORM-модели (Scan, Finding)
│   ├── logging_setup.py      # JSON-логирование + syslog
│   ├── harvester.py          # Пайплайн: загрузка → сканирование → сохранение
│   ├── scanner.py            # Интеграция с GuardDog CLI
│   ├── nexus_client.py       # HTTP-клиент для Nexus REST API
│   ├── webhooks.py           # Приём вебхуков Nexus
│   ├── api/                  # REST API (JSON)
│   │   ├── scans.py
│   │   ├── packages.py
│   │   └── findings.py
│   └── web/                  # Веб-интерфейс
│       ├── routes.py
│       ├── templates/        # Jinja2-шаблоны
│       └── static/           # CSS, JS
├── tests/                    # Тесты pytest
├── scripts/                  # Вспомогательные скрипты
├── docker-compose.yml        # Стек Docker Compose
├── Dockerfile                # Образ приложения
└── pyproject.toml            # Зависимости и настройки

Команды Makefile

Команда Описание
make install Установка зависимостей проекта
make dev Установка зависимостей для разработки
make test Запуск тестов
make lint Проверка кода через Ruff
make format Форматирование кода через Ruff
make typecheck Проверка типов через mypy
make docker-build Сборка Docker-образа
make docker-up Запуск стека Docker Compose
make docker-down Остановка стека с удалением данных
make docker-logs Просмотр логов стека
make clean Очистка артефактов сборки

Безопасность

  • Вебхуки поддерживают HMAC-SHA256 подпись через WEBHOOK_SECRET
  • Nexus-клиент использует BasicAuth для аутентификации
  • Результаты сканирования хранятся в локальной SQLite-базе
  • Временные файлы пакетов удаляются после сканирования

Лицензия

MIT

Description
No description provided
Readme 1.7 MiB
Languages
Python 80.3%
HTML 12.7%
CSS 4.3%
Shell 1.2%
JavaScript 0.6%
Other 0.9%