220 lines
7.1 KiB
Markdown
220 lines
7.1 KiB
Markdown
# CVExplorer
|
||
|
||
CVExplorer — утилита для анализа **запущенных Docker-контейнеров**:
|
||
|
||
- извлекает зависимости приложения (из контейнера **или** по ссылке на исходники)
|
||
- сравнивает версии зависимостей с базой уязвимостей **OSV.dev**
|
||
- cоздаёт отчет
|
||
- отправляет отчёт по выбранным каналам (WIP)
|
||
|
||
> На текущем этапе анализ выполняется по **манифестам зависимостей**.
|
||
|
||
---
|
||
|
||
## Возможности
|
||
|
||
- Сканирует **запущенные** контейнеры.
|
||
- Два пути извлечения зависимостей:
|
||
1. из контейнера (если манифесты присутствуют)
|
||
2. из репозитория по `source_url` (если контейнер содержит только собранный бинарник)
|
||
- Сравнивает найденные версии зависимостей с OSV.dev
|
||
- Фильтрует вывод по минимальной серьёзности (например, скрыть `LOW`).
|
||
- Есть файл конфигурации для гибкой настройки вывода
|
||
|
||
---
|
||
|
||
## Поддерживаемые манифесты
|
||
|
||
**Python:**
|
||
- `requirements*.txt`
|
||
- `Pipfile`
|
||
- `pyproject.toml`
|
||
- `poetry.lock`
|
||
|
||
**Node.js:**
|
||
- `package.json`
|
||
- `package-lock.json`
|
||
- `yarn.lock`
|
||
- `pnpm-lock.yaml`
|
||
|
||
**Go:**
|
||
- `go.mod`
|
||
- `go.sum`
|
||
|
||
**Rust:**
|
||
- `Cargo.toml`
|
||
- `Cargo.lock`
|
||
|
||
**Java:**
|
||
- `pom.xml`
|
||
- `build.gradle`, `build.gradle.kts`
|
||
|
||
**.NET:**
|
||
- `*.csproj`, `*.fsproj`
|
||
- `packages.config`
|
||
|
||
---
|
||
|
||
## Требования
|
||
|
||
- Python 3.10+ (рекомендуется 3.11+)
|
||
- Docker Engine / Docker Desktop запущен
|
||
- `git` в системе (для анализа по `source_url`)
|
||
|
||
Python-зависимости:
|
||
- `docker`
|
||
- `tqdm` (опционально, для прогресс-бара)
|
||
|
||
---
|
||
|
||
## Установка
|
||
|
||
### 1) Клонировать проект
|
||
|
||
```bash
|
||
git clone https://g.lair.moe/Chest/CVExplorer
|
||
cd CVExplorer
|
||
```
|
||
|
||
### 2) Создать виртуальное окружение
|
||
|
||
```bash
|
||
python -m venv .venv
|
||
source .venv/bin/activate
|
||
```
|
||
|
||
### 3) Поставить зависимости
|
||
|
||
```bash
|
||
pip install -U pip
|
||
pip install docker
|
||
pip install tqdm # опционально для прогресс-бара
|
||
```
|
||
|
||
---
|
||
|
||
## Запуск
|
||
|
||
Основной способ:
|
||
|
||
```bash
|
||
python run.py
|
||
```
|
||
|
||
Альтернативно (если используешь пакетный запуск):
|
||
|
||
```bash
|
||
python -m cvexplorer.main
|
||
```
|
||
|
||
> Утилита анализирует **запущенные** контейнеры. Убедись, что нужные сервисы запущены.
|
||
|
||
---
|
||
|
||
## Как работает извлечение зависимостей?
|
||
|
||
Для каждого контейнера:
|
||
|
||
1. CVExplorer ищет файлы манифестов внутри контейнера (например, `package.json`, `go.mod`).
|
||
2. Если манифестов нет, CVExplorer пытается взять `source_url` из OCI labels:
|
||
- `org.opencontainers.image.source`
|
||
- `org.opencontainers.image.url`
|
||
- (и т.п.)
|
||
3. Если `source_url` найден — репозиторий клонируется, выбирается commit (если есть `org.opencontainers.image.revision`) и парсятся манифесты в репо.
|
||
4. Дальше зависимости дедуплицируются и отправляются в OSV.dev.
|
||
|
||
---
|
||
|
||
## Конфигурация
|
||
|
||
CVExplorer читает конфиг из файла **`cvexplorer_config.json`** в рабочей директории.
|
||
Если файла нет или он некорректный — используются значения по умолчанию.
|
||
|
||
### Пример `cvexplorer_config.json`
|
||
|
||
```json
|
||
{
|
||
"output": {
|
||
"group_by_service": true,
|
||
"sections": {
|
||
"show_id_status": false,
|
||
"show_ports": false,
|
||
"show_language": false,
|
||
"show_revision": false,
|
||
"show_deps_list": false,
|
||
"show_code_files": false,
|
||
"show_errors": false
|
||
}
|
||
},
|
||
"vulns": {
|
||
"min_severity": "MEDIUM",
|
||
"include_unknown": true,
|
||
"max_affected_deps_to_show": 8,
|
||
"max_vuln_ids_to_show": 10
|
||
},
|
||
"osv": {
|
||
"enabled": true,
|
||
"chunk_size": 250,
|
||
"hydrate_details": true,
|
||
"max_pages": 5,
|
||
"timeout_sec": 30
|
||
}
|
||
}
|
||
```
|
||
|
||
### Параметры `output`
|
||
|
||
- `group_by_service` — группировать контейнеры по сервису (Compose/имя/образ).
|
||
- `sections.*` — включение/выключение блоков вывода:
|
||
- `show_id_status` — ID/статус/created
|
||
- `show_ports` — используемые порты
|
||
- `show_language` — ЯП
|
||
- `show_revision` — commit SHA
|
||
- `show_deps_list` — печатать списки зависимостей (но их может быть ооооочень много)
|
||
- `show_code_files` — найденные `main/app/index` файлы с кодом
|
||
- `show_errors` — ошибки извлечения
|
||
|
||
### Параметры `vulns`
|
||
|
||
- `min_severity` — минимальная серьёзность для отображения: `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`.
|
||
- `include_unknown` — показывать ли уязвимости с неизвестной серьёзностью.
|
||
- `max_affected_deps_to_show` — сколько «самых проблемных» пакетов показывать.
|
||
- `max_vuln_ids_to_show` — сколько ID уязвимостей выводить в примере.
|
||
|
||
### Параметры `osv`
|
||
|
||
- `enabled` — включить/выключить сравнение с OSV.dev.
|
||
- `chunk_size` — размер batch-запроса (актуально при сотнях зависимостей).
|
||
- `hydrate_details` — догружать ли детали уязвимостей (нужно для фильтрации по severity best-effort).
|
||
- `max_pages` — ограничение пагинации.
|
||
- `timeout_sec` — таймаут запросов.
|
||
|
||
---
|
||
|
||
## Прогресс-бар
|
||
|
||
Если поставить `tqdm`, появится прогресс-бар для:
|
||
- сканирования контейнеров
|
||
- batch-запросов OSV
|
||
|
||
Установка:
|
||
|
||
```bash
|
||
pip install tqdm
|
||
```
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### Нет прав на Docker
|
||
|
||
Если ошибки про доступ к Docker socket — запусти от пользователя с доступом к Docker или настрой группу `docker`.
|
||
|
||
### В контейнере нет манифестов
|
||
|
||
Это нормально для «собранных» образов. Тогда нужен `source_url` в OCI labels.
|
||
Если `source_url` отсутствует — CVExplorer сможет показать только метаданные контейнера.
|
||
Ручное добавление ссылки на знакомые вам проекты через конфигурацию — **WIP**
|
||
---
|