feat: README and examples
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
# 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**
|
||||
---
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user