
Офлайн-ориентированный трекер найденных уязвимостей, который выполняет параллельный поиск по 11 базам данных CVE, добавляет обогащение EPSS/KEV и управляет сроками скоординированного раскрытия уязвимостей.
Статический клиентский трекер уязвимостей на Astro + React — также упакован как нативное десктопное приложение для Linux (Tauri v2). Фиксируйте находки безопасности, отслеживайте процесс скоординированного раскрытия, выполняйте поиск по 11 живым базам уязвимостей параллельно и просматривайте свежие CVE — в браузере или как десктопное приложение, без бэкенда.
localStorage (без сервера и аккаунта)Трекер (/tracker) — это одностраничное приложение с пятью вкладками:
Представление управления вашими находками:
Одновременный запрос ко всем включённым базам параллельно по одной строке запроса:
Просмотр свежих уязвимостей без ввода запроса:
Панель управления подключениями к базам:
.env на этапе сборки{query}, необязательный bearer-ключ), его проверка или удаление; подключённые пользовательские базы появляются дополнительными чипами в представлении поискаFinding — основная запись. Поля:
Валидация выполняется в форме: обязательные поля, формат URL, длина описания и диапазон оценки CVSS.
Интегрировано 11 баз, плюс обогащение EPSS. Семь подключаются напрямую без ключа; для четырёх нужен учётные данные из .env.
Не интегрировано (с причинами): Snyk (ограничено организацией, нет публичного поискового API), JFrog Xray (self-hosted, возвращает артефакты, а не записи CVE), Trivy (CLI-сканер, нет REST API), MSRC (ежемесячные документы CVRF, не поддерживают поиск по ключевым словам), VulnCheck (только массовая резервная конечная точка), Debian/Ubuntu (дампами по несколько ГБ, не подходят для клиентского поиска), Exploit-DB/Sploitus (нет публичного API), CNVD/CNNVD (ручная загрузка XML), Sonatype OSS Index (на основе purl/компонентов, не по ключевым словам).
Дизайн-система: тема «Dark Sunset Boulevard» — тёмные поверхности с фиолетовым оттенком (ink-950 #1A2226, ink-900 #223036, ink-800 #264653), тёплый песочный текст (ink-100 #F2EAE0, ink-400 #A49A8C) и оранжевый акцент цвета жжёного апельсина (#E76F51). Все цвета — токены Tailwind 4, определённые в src/styles/global.css — без жёстко прописанных hex в компонентах.
Требуется Node.js >= 20.```bash
npm install
npm run dev
npm run check
npm run build
npm run preview
Сборка создаёт полностью статический сайт (`dist/`) — его можно развернуть на любом статическом хостинге (GitLab Pages, Netlify, Cloudflare Pages, GitHub Pages, nginx…). Эта же сборка также упаковывается в нативное десктопное приложение — см. [Нативное десктопное приложение](#native-desktop-app).
---
## Нативное десктопное приложение
**Одна кодовая база — любой формат поставки.** Один и тот же исходный код собирает веб-сайт, десктопные приложения и Android-приложение — нет отдельных веток для веба и приложений. Приложения представляют собой статическую сборку, обёрнутую в небольшую **Tauri v2** оболочку на Rust, которая отображает её в системном webview (WebKitGTK на Linux, WKWebView на macOS, WebView2 на Windows, Android WebView). Никакого сервера и вкладки браузера; настройки и результаты сохраняются в собственном каталоге данных приложения.
### Linux (по умолчанию)
Поставляемые десктопные сборки ориентированы на Linux (`.deb`, `.rpm`, AppImage).
**Системные зависимости (Debian/Ubuntu):**```bash
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
Разработка (горячая перезагрузка: dev-сервер Astro + окно Tauri):```bash npm run tauri:dev
**Создание устанавливаемых пакетов** (`.deb`, `.rpm`, AppImage — вывод в `src-tauri/target/release/bundle/`):```bash
npm run tauri:build
Оболочка Rust намеренно минималистична — в v1 нет ни одной IPC-команды; вся логика остаётся в веб-слое, поэтому браузерная сборка и десктопное приложение ведут себя одинаково.
Поддержка macOS не включена в конфигурации по умолчанию — поставляемые сборки предназначены только для Linux. Сама кодовая база полностью кроссплатформенна (веб-слой работает в любом браузере, а оболочка Rust не содержит ни одной IPC-команды), поэтому включение macOS — это небольшое изменение конфигурации плюс сборка на Mac. Полное руководство см. в docs/macos-development.md: предварительные требования, включение цели dmg, иконки, подпись и нотаризация, а также пример CI для GitLab.
Поддержка Windows не включена в конфигурации по умолчанию — поставляемые сборки предназначены только для Linux. Кодовая база полностью кроссплатформенна, а сборки для Windows выполняются на машине с Windows 11 и инструментарием MSVC (WebView2 предустановлен). Полное руководство см. в docs/windows-development.md: предварительные требования, включение целей nsis / msi, иконки, подпись кода и SmartScreen, а также пример CI для GitLab.
Цель Android не инициализирована в репозитории — одна команда создаёт её каркас (npm run tauri android init). Кодовая база полностью кроссплатформенна (веб-слой работает в Android WebView, а интерфейс трекера уже адаптирован для телефонов). Полное руководство см. в docs/android-development.md: предварительные требования (Android Studio, SDK, NDK, JDK 17), инициализация цели, сборка APK/AAB, а также пример CI для GitLab.
Четыре источника поиска требуют учётных данных. Скопируйте .env.example в .env, заполните ключи и пересоберите:
Примечание по безопасности: это статический сайт — переменные
PUBLIC_*на этапе сборки встраиваются в клиентский бандл и видны в исходном коде страницы. Используйте ключи с минимальными правами или серверный прокси для настоящей секретности. Источники без ключа просто показывают чип с ошибкой; остальной поиск продолжает работать.
Совет: эти ключи также можно ввести на вкладке Настройки приложения — ключи времени выполнения переопределяют значения из
.envна этапе сборки, пересборка не нужна.
Файлы .env игнорируются git; коммитится только .env.example.
Включение/выключение баз данных и API-ключи управляются на вкладке Настройки во время выполнения — не нужно редактировать файлы или пересобирать. Значения по умолчанию находятся в src/tracker/lib/dbConfig.ts, а переопределения времени выполнения хранятся в приложении (localStorage, ключ settings:all).
Приоритет: настройки времени выполнения (вкладка «Настройки») > значения .env на этапе сборки > значения по умолчанию из dbConfig.ts.
Каждая запись конфигурации содержит:
enabled — состояние по умолчанию; вкладка «Настройки» может переопределить его для каждого сеансаsearch / browse — в каких представлениях участвует источникneedsKey + keyVar — помечает источники, которые используют учётные данные (из .env или вкладки «Настройки»)Интерфейс полностью строится на основе действующей конфигурации: getSearchSources() (чипы поиска) и getBrowseSources() (чипы обзора) фильтруются по включённым источникам, а адаптеры фильтруются во время запроса — отключение источника в настройках немедленно убирает его из интерфейса и из запросов.
Пользовательские базы данных хранятся в тех же настройках времени выполнения (customDbs). Каждая запись имеет имя, URL (опционально содержащий плейсхолдер {query} — в противном случае запрос добавляется как ?q=) и опциональный bearer-ключ. Они работают только в режиме поиска: появляются как дополнительные чипы в представлении поиска и запрашиваются параллельно со встроенными источниками. Ответы принимаются в формате CVE JSON 5.0 ({ "vulnerabilities": [{ "cve": ... }] }) или как простой массив записей с гибкими именами полей.
Весь доступ к базам данных находится в src/tracker/lib/ и разделён по зонам ответственности (dbSearch.ts — это barrel-файл, реэкспортирующий прежнюю публичную поверхность):
dbFetch.ts — хелпер fetch с таймаутом + общие константыdbAdapters.ts — 11 встроенных адаптеров поиска + парсеры записейdbBrowse.ts — 4 адаптера обзора + конвейер browseDatabasesdbCustom.ts — адаптер пользовательской базы данныхdbPipeline.ts — механизмы merge / KEV / EPSS + `searchDatabases````
query ──► Promise.all over enabled adapters ──► normalizeDbItem
──► mergeDbItems (dedup by CVE / ID / title, cross-merge)
──► attachKevBadges (CISA KEV catalog, cached)
──► enrichWithEpss (FIRST EPSS API, batched by CVE)
──► sorted results + per-source statuses + timing- **Адаптеры** — по одному на источник, каждый возвращает нормализованные `RawDbItem`s. Адаптеры с ключами выбрасывают понятную ошибку «no API key configured», когда ключ отсутствует.
- **Объединение** — один и тот же CVE, найденный в нескольких источниках, становится одной карточкой; поля (summary, severity, CVSS, CWEs, refs, sources) объединяются из всех источников-участников.
- **Значки KEV** — каталог CISA загружается один раз и кэшируется; элементы из него получают значок «Known Exploited».
- **EPSS** — пакетный запрос к `api.first.org`; на каждой карточке показывается оценка EPSS и перцентиль.
- **Изоляция сбоев** — каждый адаптер перехватывает собственные ошибки и сообщает о них через колбэк статуса; один недоступный источник никогда не блокирует остальные.
Конвейер **Browse** — это тот же механизм merge/KEV/EPSS для четырёх источников Browse, с пагинацией (`hasMore`, когда любой из источников вернул полную страницу).
**Автономный режим** заменяет живой конвейер загруженным снимком: Search и Browse читают кэш IndexedDB (`src/tracker/lib/offline.ts`), пропускают обогащение EPSS и добавляют значки KEV только в том случае, если фид CISA KEV также был загружен. Источники без загруженного снимка показывают чип «error / not downloaded» вместо зависания. **Пользовательские базы данных** запрашиваются через тот же интерфейс адаптеров — плейсхолдер `{query}` в URL подставляется (или добавляется `?q=`), при необходимости bearer-ключ отправляется в заголовке `Authorization`, а ответы нормализуются из CVE JSON 5.0 или простого массива.
---
## Хранение данных
Находки хранятся в `localStorage` под ключом `findings:all` — без сервера, без аккаунта, работает офлайн.
- Записи дебаунсятся при каждом изменении и сохраняются автоматически
- Если API хранилища браузера недоступен (или присутствует API хост-хранилища артефактов), приложение корректно переключается на запасной вариант
- Повреждённый payload считается пустым, а не приводит к падению
- При сбое сохранения показывается баннер с кнопкой **Повторить**
> Данные хранятся в профиле браузера. Очистка данных сайта удалит ваши находки — если нужна резервная копия, сначала экспортируйте их в CSV/Markdown.
**Автономные снимки** хранятся в IndexedDB (база данных `vulnbook-offline`, хранилища `items` + `meta`) — загружаются по каждому источнику со вкладки «Настройки» и используются в Search/Browse, пока включён автономный режим. Они переживают перезагрузки и удаляются только по клику на **Удалить** для этого источника или при очистке данных сайта.
---
## Экспорт
Из представления «Находки» экспортируйте **текущий отфильтрованный и отсортированный** список:
- **CSV** — 15 столбцов (title, project, repo URL, severity, CVSS, status, CWE, CVE, affected versions, discovery/reported/disclosure dates, references, notes, tags). Корректное экранирование/заключение в кавычки для запятых, кавычек и переводов строк.
- **Markdown** — таблица в стиле GitHub с теми же столбцами.
Файлы называются `findings-YYYY-MM-DD.csv` / `.md` и загружаются автоматически.
---
## AI ChatBox
Встроенный ИИ-ассистент внутри трекера — **оверлейная боковая панель**, которая выезжает поверх контента, не перестраивая его. Полное руководство (настройка провайдеров, рекомендации по безопасности, устранение неполадок) — в **[docs/ai-chatbox.md](https://gitlab.com/t-beckett/vulnbook-deletion_scheduled-85395299/-/blob/main/docs/ai-chatbox.md)**.
- **Пять провайдеров** — OpenAI, Claude (Anthropic), Google Gemini, **Ollama** (локальный, офлайн) и **OpenCode Zen** (включая бесплатные модели). Настройка (ключ + модель) выполняется в приложении, сохраняется в `localStorage` (`chat:config`) и отправляется только на endpoint самого провайдера
- **Специализация по проекту** — каждый разговор основан на встроенном **пакете знаний** о vulnbook (архитектура, модель данных, источники БД, соглашения); переключается через **Контекст проекта** в панели конфигурации
- **Потоковые ответы** — вывод markdown в реальном времени с кнопкой **Остановить**; при необходимости автоматически срабатывает запасной режим без стриминга
- **Слэш-команды** — введите `/` в поле ввода: `/mcp` и `/skill` открывают AI Marketplace, `/new` начинает разговор, `/clear` очищает его, `/help` показывает список команд
- **Вызов инструментов (in-browser MCP runtime)** — подключённые MCP-серверы предоставляют реальные инструменты, которые ассистент может вызывать во время разговора: живой поиск по CVE/базам данных, запросы KEV, находки пользователя и экспорт. Инструменты выполняются локально в браузере (без бэкенда) и работают во **всех трёх семействах протоколов** — в стиле OpenAI (OpenAI, Ollama, OpenCode Zen), Anthropic и Gemini
- **AI Marketplace** — вкладка боковой панели со списком доступных **MCP** и **Skill** в виде сетки; на карточках MCP отображается чип **«N tools»** и переключатель **Включить** (сохраняется), на карточках навыков — **Подключить** / **Скачать**
- **История чатов** — разговоры сохраняются (`chat:history`, с ограничением, при котором самые старые записи удаляются первыми)
> **Безопасность:** ключи остаются локальными и отправляются только провайдеру; markdown ассистента рендерится через строгий санитайзер (без сырого HTML). MCP-инструменты выполняются **в браузере** только с данными самого приложения и публичными API — каждый инструмент проверяет свои аргументы, выполняется с таймаутом 12 секунд и обрезает вывод до 4 000 символов; произвольный код не выполняется.
---
## Тестирование
У проекта нет фреймворка для модульных тестов (устоявшееся решение) — проверка представляет собой трёхэтапный шлюз:```bash
# 1. Type-check
npm run check
# 2. Build
npm run build
# 3. E2E smoke test (Playwright, 16 checks)
npx http-server dist -p 8899 -a 127.0.0.1 &
NODE_PATH=<path-to-playwright-node_modules> node scripts/smoke.cjs
Смоук-тест (scripts/smoke.cjs) покрывает: рендер и гидратацию целевой страницы, гидратацию островка трекера, CRUD для находок, сохранение localStorage при перезагрузке, список и элементы управления экспортом, модальное окно деталей (открытие/Escape), удаление, поиск по базе данных, создающий карточки результатов, режим просмотра (browse view), создающий карточки результатов, вкладку настроек (отключение источника убирает его чип, повторное включение возвращает его), офлайн-режим (переключатель показывает офлайн-баннер в разделе «Поиск» и восстанавливает живой режим) и проверку формы пользовательской базы данных (недопустимый URL отклоняется).
PLAYWRIGHT_CHROMIUM_PATH или путь к кэшу по умолчаниюДля изменений в нативном приложении дополнительно запустите npm run tauri:build (см. Нативное десктоп-приложение).
├── src/ │ ├── components/ # Shared Astro components + animation primitives │ │ └── anim/ # Skeleton, Spinner, FadeInUp, CountUp │ ├── layouts/ # SiteLayout (fonts, meta, theme) │ ├── pages/ # index.astro (landing), tracker.astro, 404.astro │ ├── styles/ # global.css — Tailwind 4 design tokens │ └── tracker/ │ ├── components/ # Tracker UI │ │ ├── TrackerApp.tsx # Shell: tabs, modals, state │ │ ├── Dashboard.tsx # Stats + charts + deadlines │ │ ├── FindingsList.tsx / FilterBar.tsx │ │ ├── DbSearchView.tsx / BrowseView.tsx / SettingsView.tsx │ │ ├── FindingFormModal.tsx / FindingDetailModal.tsx │ │ ├── ConfirmDeleteDialog.tsx / EmptyState.tsx / ErrorBanner.tsx │ │ ├── SourceChip.tsx / SearchResultCard.tsx / StatCard.tsx / badges.tsx │ │ ├── AiMarketplace.tsx # AI Marketplace grid (MCP/Skill cards, tool counts, enable toggles) │ │ └── chat/ # AI ChatBox UI │ │ ├── AiChatSidebar.tsx # Overlay sidebar + the tool-calling agent loop │ │ ├── ChatMessageList.tsx # Renders messages incl. inline tool calls │ │ ├── ChatComposer.tsx / ChatConfigPanel.tsx / ChatHistoryList.tsx │ └── lib/ # Logic │ ├── types.ts # Finding, DbItem, KevEntry, View, … │ ├── constants.ts # Severity/status order + styles, button classes │ ├── dbConfig.ts # ← per-source defaults (on/off, key vars) │ ├── settings.ts # ← runtime settings store (Settings tab overrides) │ ├── offline.ts # IndexedDB offline snapshot store (download/remove/query) │ ├── dbSearch.ts # barrel: re-exports the db layer (see "How the Search Pipeline Works") │ ├── dbFetch.ts # fetch-with-timeout helper + shared constants │ ├── dbAdapters.ts # 11 built-in search adapters + record parsers │ ├── dbBrowse.ts # browse adapters + browseDatabases pipeline │ ├── dbCustom.ts # user-configured custom database adapter │ ├── dbPipeline.ts # merge/KEV/EPSS pipeline + searchDatabases │ ├── findings.ts # CRUD + validation │ ├── storage.ts # localStorage + artifact-API fallback │ ├── export.ts # CSV / Markdown export │ ├── format.ts # date/URL/id helpers, cvssToSeverity │ └── chat*.ts # AI ChatBox logic (see "AI ChatBox"): chatStore (config/history), │ # chatProvider (3 wire families + tool calling), chatTools (tool │ # registry + in-browser MCP runtime), chatMcp (enabled-state), │ # chatCatalog / chatKnowledge / chatFindings / chatCommands / chatMarkdown ├── scripts/smoke.cjs # Playwright E2E smoke test (16 checks) ├── docs/ # Developer guides (macOS, Windows 11, Android development) ├── src-tauri/ # Tauri v2 native shell (Rust, minimal) ├── research/ # Vulnerability database & tooling research notes ├── .env.example # Documented API-key template └── astro.config.mjs
---
## Исследовательские заметки
Каталог `research/` содержит фоновые исследования, которые легли в основу интеграций баз данных:
- **`vulnerability-databases.md`** — каталогизировано ~60 баз данных (модель доступа, доступность API, предостережения), включая изменения обогащения NVD от апреля 2026 г., детали API EUVD/OpenCVE/VulDB и список «почему нет»
- **`vulnerability-finding-tools.md`** — более широкий ландшафт инструментов поиска уязвимостей (SAST/SCA/fuzzing/pentest) и конвейер для индивидуального специалиста
---
## Процесс проектирования и планирования
Этот проект следует рабочему процессу «проектирование → план → выполнение».
Новые возможности начинаются с документа проектирования, проходят проверку, затем планируются и выполняются в виде микро-задач. Полные правила (ветвление, контроль верификации, стиль коммитов, правила доступности) описаны в `CONTRIBUTING.md`.
---
## Лицензия
[MIT](https://gitlab.com/t-beckett/vulnbook-deletion_scheduled-85395299/-/blob/main/LICENSE) © 2026 T. Beckett
| Поле | Описание |
|---|
id | Уникальный идентификатор |
projectName | Проект, к которому относится находка (обязательно) |
repoUrl | URL репозитория (обязательно, должен быть корректным URL) |
title | Короткое название (обязательно) |
description | Подробное описание (обязательно, ≥ 10 символов) |
severity | Critical / High / Medium / Low |
cvssScore | Оценка CVSS 0–10 (необязательно) |
cweId | Идентификатор CWE, например CWE-79 |
cveId | Идентификатор CVE, например CVE-2021-44228 |
affectedVersions | Затронутые диапазоны версий |
status | New / Reported / Acknowledged / Fixed / Disclosed |
discoveryDate | Когда вы обнаружили находку |
reportedDate | Когда вы сообщили о ней вендору |
disclosureDeadline | Дедлайн скоординированного раскрытия (управляет оповещениями на дашборде) |
referenceLinks | Список ссылок на источники |
notes | Произвольные заметки |
tags | Список тегов (используется для фильтрации) |
createdAt / updatedAt | Метки времени |
| № | Источник | Доступ | Поиск | Обзор | Примечания |
|---|
| 1 | NVD (NIST) | Прямой | ✅ | ✅ | NVD API 2.0; окно 30 дней в обзоре |
| 2 | CIRCL | Прямой | ✅ | ✅ | Поиск CVE + лента «last» (форматы OSV/CSAF) |
| 3 | GitHub Advisories | Прямой | ✅ | ✅ | GHSA API |
| 4 | OSV (Google) | Прямой | ✅ | — | Уязвимости экосистем с открытым исходным кодом |
| 5 | CISA KEV | Прямой | ✅ | ✅ | Каталог известных эксплуатируемых уязвимостей |
| 6 | Red Hat | Прямой | ✅ | — | База CVE Red Hat |
| 7 | EUVD (ENISA) | Прямой | ✅ | — | Европейская база уязвимостей |
| 8 | Vulners | ключ из .env | ✅ | — | PUBLIC_VULNERS_API_KEY |
| 9 | MEND | токен из .env | ✅ | — | PUBLIC_MEND_API_TOKEN (поиск по CVE ID) |
| 10 | VulDB | ключ из .env | ✅ | — | PUBLIC_VULDB_API_KEY (на основе кредитов) |
| 11 | OpenCVE | токен из .env | ✅ | — | PUBLIC_OPENCVE_API_TOKEN |
| — | EPSS (FIRST) | Прямой | — | — | Только обогащение: оценка CVE 0–1 + процентиль |
| Слой | Выбор |
|---|
| Фреймворк | Astro 6 (статическая генерация) |
| UI | Островки React 19 |
| Стилизация | Tailwind CSS 4 (классы на основе токенов) |
| Графики | Recharts |
| Иконки | lucide-react |
| Анимация | framer-motion |
| Десктоп | Tauri v2 (Linux: deb / rpm / AppImage; Windows: см. Разработка под Windows 11; macOS: см. Разработка под macOS) |
| Мобильные | Android через Tauri v2 — см. Разработка под Android |
| AI-чат | Встроенный чат — OpenAI / Claude / Gemini / Ollama / OpenCode Zen (см. AI-чат) |
| Язык | TypeScript (строгий режим) |
| Source | Variable | Where to get it |
|---|
| Vulners | PUBLIC_VULNERS_API_KEY | Аккаунт Vulners → API-ключи |
| MEND | PUBLIC_MEND_API_TOKEN | MEND SCA API 2.0 (JWT bearer-токен) |
| VulDB | PUBLIC_VULDB_API_KEY | Аккаунт VulDB → API-ключ (на основе кредитов) |
| OpenCVE | PUBLIC_OPENCVE_API_TOKEN | Организация OpenCVE → API-токены |