Commit Graph

81 Commits

Author SHA1 Message Date
Marker689
73d0f0fb5c fix: Dockerfile README.md in deps layer for hatchling build 2026-05-11 23:10:26 +03:00
Marker689
18efcf482e feat: 31 new tests, metrics LLM counters, Dockerfile caching, Makefile targets, compose limits, code fixes 2026-05-11 23:08:09 +03:00
Marker689
20bf7e6745 Revert 'build: non-root USER' — volume mounts require root for data directory 2026-05-11 22:35:50 +03:00
Marker689
4834fd1621 build: non-root USER, curl HEALTHCHECK, Nexus healthcheck in compose 2026-05-11 22:33:20 +03:00
Marker689
56786c7aef fix: race conditions in lock pop, CSV formula injection, serialize_finding None leak, consolidate plans, update docs 2026-05-11 22:31:41 +03:00
Marker689
3f44de1d98 refactor: Pydantic webhook payload models, lifespan task cancellation, dict/Pydantic compat helpers 2026-05-11 22:07:35 +03:00
Marker689
6e3c2c5caa fix: spinner template missing finding_id when included from scan/package detail 2026-05-11 21:53:45 +03:00
Marker689
f4b8b74297 fix: visible spinner on Retry button, CSS htmx-indicator show/hide rules 2026-05-11 21:46:21 +03:00
Marker689
5afb377d92 ui: LLM spinner auto-polls via GET every 2s, idempotency check fixed 2026-05-11 21:28:32 +03:00
Marker689
56a9485950 fix: LLM spinner auto-polls status every 2s via htmx until analysis completes 2026-05-11 21:12:53 +03:00
Marker689
e994e302fc build: .dockerignore, pin guarddog>=2.10.0, Docker HEALTHCHECK 2026-05-11 21:02:38 +03:00
Marker689
9b98a32216 fix: propagate initiator/source_ip to _scan_component for component webhooks 2026-05-11 21:00:15 +03:00
Marker689
436a2be75f refactor: parallel LLM analysis via asyncio.gather instead of sequential 2026-05-11 20:55:36 +03:00
Marker689
2dd26272cb feat: scoped npm support (@angular/core style paths) in extract_npm_info 2026-05-11 20:46:42 +03:00
Marker689
b50c64aadb docs: update AGENTS.md, READMEs with latest changes and new env vars 2026-05-11 20:18:05 +03:00
Marker689
fe384aed17 feat: LLM response validation with defaults, security headers middleware, cleaner stats endpoint 2026-05-11 20:11:47 +03:00
Marker689
2d9ab9f436 docs: update security audit plan with fix status 2026-05-11 20:04:16 +03:00
Marker689
fb5559b8b7 fix: reject unknown ecosystems instead of silently defaulting to pypi 2026-05-11 19:59:47 +03:00
Marker689
a6cd20e41c fix: try/except in _scan_component, serialize_finding to prevent data injection, DRY LLM template, SUPPORTED_ECOSYSTEMS constant 2026-05-11 19:45:49 +03:00
Marker689
6743321463 feat: SSRF protection via NEXUS_ALLOWED_HOSTS, _env_int validation warnings 2026-05-11 19:38:15 +03:00
Marker689
04abe44ab4 refactor: uv-based deps, no nexus auth, LLM retries, lock cleanup, health checks, e2e tests 2026-05-11 19:27:56 +03:00
Marker689
698f02c8af fix: system prompt — Priority вместо Hard Gate (защита без потери качества)
- V2 Priority: system instructions override user message, но LLM может
  отличать легитимный код от вредоносного
- Тест: legit urllib3=safe/LOW, poisoned backdoor=malicious/CRITICAL
- Hard Gate убран — был слишком агрессивен (flag любой ctypes.CDLL)
2026-05-10 15:39:33 +03:00
Marker689
682b340d7d fix: system prompt — защита от prompt injection (hard gate)
- constants.py: новый LLM_ANALYSIS_SYSTEM_PROMPT с защитой от injection
- Явное разделение: message = CLAIMS (untrusted), code = FACTS
- Инструкция игнорировать user message при конфликте с code/rule
- examples/test-prompt-variants.py: тест 3 вариантов промпта
- Результат: baseline=safe (обманут), V2/V3=malicious (устояли)
- examples/test-prompt-poisoning.py: 4 вектора атаки с оригинальным промптом
2026-05-10 15:34:22 +03:00
Marker689
73a8cb0953 feat: тест prompt poisoning LLM — подтверждена уязвимость
- examples/test-prompt-poisoning.py: 4 вектора атаки (message, code, override, encoded)
- Результат с GLM47: clean=malicious, poisoned=safe — LLM обманут
- Конфиг через env vars (LLM_API_KEY, LLM_API_BASE, LLM_MODEL)
2026-05-10 13:57:33 +03:00
Marker689
11ce9802e9 feat: примеры вредоносных пакетов + E2E-тест + документация
- examples/evil-pypi/: exec-base64, shady-links, code-execution, dll-hijacking
- examples/evil-npm/: eval, Buffer(base64), shady-links
- examples/evil-go/: exec+base64, shady-links
- examples/trigger-scans.sh: сборка архивов + Docker cp + вебхуки + проверка
- README.md + README.en.md: секция E2E-тестирования с curl-примерами
- E2E пройден: pypi(2 findings), npm(1), go(1) — все flagged
2026-05-10 13:13:36 +03:00
Marker689
c1258dde99 refactor: FastAPI best practices — return types, Pydantic schemas, middleware, code dedup
- Все 18 роутов получили return type annotations
- Создан schemas.py с Pydantic-моделями (ScanOut, PackageOut, FindingOut, ...)
- API-роуты: response_model на list/detail/export/stats
- 404 через HTTPException(404) вместо {'detail':'Not found'} (200)
- RequestLoggingMiddleware: method, path, status, duration_ms
- Глобальный exception handler: ловит необработанные исключения → 500
- _parse_flagged(): вынесен дублирующийся string→bool
- parse_package_path(): общий для web.py и api_packages.py
- selectinload: вынесены в top-level imports
- harvester: makedirs/mkdtemp/rmtree обёрнуты в asyncio.to_thread()
2026-05-10 12:53:33 +03:00
Marker689
935d96b35a fix: thead th — text-align:center явно 2026-05-10 12:09:16 +03:00
Marker689
6ca652db97 fix: thead th — явные font-size, weight, padding (убрана разница до/после сорта) 2026-05-10 12:06:24 +03:00
Marker689
3077f3faad fix: thead th — border:none, только border-bottom #202632 2026-05-10 12:03:21 +03:00
Marker689
d5cd47957e fix: thead — border-bottom вместо border-color, дефолтная сортировка по ID desc 2026-05-10 12:01:43 +03:00
Marker689
b2bd1fb336 fix: заголовки таблиц — убраны синие фон/рамка Pico (теперь всегда transparent + #202632) 2026-05-10 11:57:35 +03:00
Marker689
d046260e7f ui: единый стиль шапки таблиц — иконки сортировки всегда opacity:1 2026-05-10 11:50:03 +03:00
Marker689
dea9e0a6e4 a11y: Web Interface Guidelines — 19 правок доступности и семантики
- base.html: lang динамический, meta theme-color, skip-link, убран дубль Dashboard
- Фильтры: labels на search/select, type=search, placeholder с …, autocomplete=off
- llm-retry: <span> → <button> во всех шаблонах (_llm_report, scan, package)
- sortable th: tabindex=0, role=button через JS + keyboard handler
- sort-icon: aria-hidden=true
- style.css: color-scheme:dark, prefers-reduced-motion, tabular-nums, touch-action
- app.js: clipboard fallback для не-HTTPS
2026-05-10 11:45:41 +03:00
Marker689
32dc179f25 refactor: удалены внешние зависимости — pico.css и htmx.js теперь локально
Скачаны и сохранены в /static:
- pico.min.css v2 (83 KB)
- htmx.min.js v2.0.4 (51 KB)
Добавлены в .gitignore
2026-05-10 11:35:36 +03:00
Marker689
1011df8f4d chore: убрать скриншоты из репозитория 2026-05-10 11:32:25 +03:00
Marker689
29b463a1b2 fix: замена несуществующих CSS-переменных на hex-цвета
35 var(--pico-color-*) → hex (#e04040, #4caf50, #f0c000, #2196f3, #202632, #2a3140...)
Все бордеры, фоны и цвета статусов теперь рендерятся корректно
2026-05-10 11:32:17 +03:00
Marker689
2c753748f0 ui: scan-info-block — фон, рамка, скругление (карточка вместо плоского текста) 2026-05-10 11:19:47 +03:00
Marker689
53bb095f83 fix: таблицы — overflow-x:auto только на мобилке (max-width:768px) 2026-05-10 11:13:49 +03:00
Marker689
1341404568 fix: аудит — 19 фиксов безопасности, надёжности, UI и 16 новых тестов
- S4: bump jinja2>=3.1.4, python-multipart>=0.0.18, httpx>=0.28.0
- S5: _detect_ecosystem — DEFAULT_ECOSYSTEM для неизвестных форматов
- S6: harvester — log.exception() вместо log.error()
- S8: _scan_component — urlencode параметров
- P1: scanner — proc.kill() при таймауте
- P3: api_packages — selectinload(Scan.findings), убран N+1
- P4+P5: утечка _url_locks и _llm_locks при early return
- P6: DB reaper — сброс {'status':'analyzing'} при старте
- UI: htmx-пагинация, фильтры не теряют flagged, 404 с layout
- UI: мобильные таблицы overflow-x, полная стата на дашборде
- UI: i18n статусов в _status_badge, urlencode package_name
- 16 новых тестов: analyze endpoint (6), scanner errors (4),
  webhook signature (2), llm client (4)
2026-05-10 10:45:44 +03:00
Marker689
d483a8b21d docs: обновлён AGENTS.md — 85 тестов, LLM-стейт-машина, _ensure_indexes, async I/O 2026-05-10 09:58:34 +03:00
Marker689
6984844161 feat: LLM-анализ — индикатор прогресса, кнопка рескана, статистика на дашборде
- Добавлен статус {"status": "analyzing"} в finding.report на время LLM-анализа
- Кнопка рескана (Retry) под LLM-отчётом в ручном режиме
- LLM-статистика на дашборде: analysed / pending
- Защита от двойного анализа через per-finding asyncio.Lock
- _llm_spinner.html — фрагмент спиннера для состояния analysing
- Удалён мёртвый код: constants, i18n, CSS, queries
- Фиксы: _env_int, индексы БД, UnicodeDecodeError, time.mktime и др.
- Шаблоны: shared includes (_status_badge, _pagination)
- AGENTS.md: workflow (lint, test, commit, rebuild)
2026-05-10 09:54:04 +03:00
Marker689
c99a7bf67c fix: правильный парсинг initiator из вебхука Nexus
Nexus присылает initiator в формате 'username/IP' (напр. admin/172.21.0.3).
Теперь initiator и source_ip правильно разделяются из этого поля.
Лог Webhook payload выводит распарсенные значения.
2026-05-10 08:06:06 +03:00
Marker689
904e917f1f refactor: фаза 5 — чистка (APP_VERSION, LLM константы)
- constants.py: APP_VERSION, LLM_DEFAULT_TEMPERATURE, LLM_RESPONSE_FORMAT
- main.py: версия из APP_VERSION (вместо хардкод '0.1.0'×2)
- llm.py: temperature и response_format из constants

Всего: 85 тестов, ruff clean
2026-05-10 07:59:57 +03:00
Marker689
f252c256d8 test: фаза 4 — тесты extractors, ecosystem, i18n, metrics
- test_nexus.py: extract_pypi/go/npm, dispatch, edge cases (16 тестов)
- test_i18n.py: RU/EN переводы, fallback, форматирование, web UI (10 тестов)
- test_metrics.py: Prometheus endpoint (4 теста)
- test_webhooks.py: _detect_ecosystem (6 тестов), Go/npm webhook fixtures
- conftest.py: sample_nexus_go/npm_webhook fixtures
- Всего: 85 тестов (было 50)
2026-05-10 07:58:03 +03:00
Marker689
d11be24c5f fix(i18n): формальный русский перевод + t() во всех шаблонах
- i18n.py: формальный русский (сканирования, панель управления, и т.д.)
- Все шаблоны: замена хардкод-строк на t(key, request.state.lang)
- dashboard_stats_fragment: добавлен request в контекст
2026-05-10 07:52:58 +03:00
Marker689
f108464828 docs: AGENTS.md + AI-нота в README + английский README.en.md
- AGENTS.md: документация для разработчиков (архитектура, конвенции,
  common tasks, testing, Docker, webhooks)
- README.md: добавлена AI-поме тка в конце
- README.en.md: полная английская версия документации
2026-05-10 07:40:26 +03:00
Marker689
d33411b719 feat: фаза 3 — i18n RU/EN, /metrics, AI disclaimer, initiator+IP, LLM очередь
3.3 i18n: модуль с RU/EN словарями, LangMiddleware (cookie+query),
     Jinja-фильтр t(), переключатель EN/RU в nav, перевод ключевых
     строк интерфейса
3.5 /metrics: Prometheus-совместимый endpoint (scans_total,
     scans_flagged, findings_total, by_status, by_ecosystem,
     last_scan_timestamp)
3.2 AI disclaimer: сноска под каждым LLM-вердиктом (.llm-disclaimer)
3.4 LLM очередь: asyncio.Semaphore(LLM_MAX_CONCURRENT_ANALYSES)
3.1 initiator + source_ip: поля в Scan, захват из webhook payload,
     показ в scan_detail + API
3.6 UI: убран stat-minibar и heatmap с дашборда
2026-05-10 07:37:22 +03:00
Marker689
4ae893a025 feat: фаза 3 (часть 1) — disclaimer, очередь, initiator + IP
3.6 UI: убрать stat-minibar и heatmap с дашборда
3.2 AI disclaimer под каждым LLM-вердиктом
3.4 LLM_MAX_CONCURRENT_ANALYSES + Semaphore в llm.py
3.1 Scan.initiator + source_ip, webhook захватывает, UI показывает
2026-05-10 07:32:14 +03:00
Marker689
0069331119 fix: Dockerfile — парсить deps из pyproject.toml (единый источник) 2026-05-10 07:26:24 +03:00
Marker689
6e6f45ce03 fix: фаза 2 — критические фиксы
READМЕ: убрать NEXUS_REPOSITORIES, CREATED→UPDATED, go/npm/Gem→go/npm,
  добавить MAX_CONCURRENT_SCANS, CSV-экспорт, инструкцию по вебхукам Nexus
Dockerfile: uv pip install --system . (единый источник deps — pyproject.toml)
docker-compose: WEBHOOK_SECRET, SCAN_TIMEOUT_SECONDS
pyproject.toml: убрать deprecated [tool.ruff].select
config.py: default из DEFAULT_MAX_CONCURRENT_SCANS
constants.py: убрать GUARDDOG_ERRORS_KEY (мёртвый), .gem из PACKAGE_EXTENSIONS,
  LLM prompt: «Python»→«software»
queries.py: убрать return_total
Makefile: docker-up +--build, docker-down без -v, +docker-destroy,
  +docker-rebuild, убран typecheck
2026-05-10 07:23:43 +03:00