diff --git a/docs/backlog/dependency-updates-and-security-audit.md b/docs/backlog/dependency-updates-and-security-audit.md new file mode 100644 index 00000000..9df72976 --- /dev/null +++ b/docs/backlog/dependency-updates-and-security-audit.md @@ -0,0 +1,117 @@ +# Обновление зависимостей: устаревшие версии и аудит безопасности + +Статус: **зафиксировано в беклоге, зависимости не менялись.** Это снимок состояния +на дату проверки — список задач на обновление, а не баг. Бо́льшая часть версий +**унаследована от upstream `docmost/main`**, поэтому массовые бампы разумно делать +вместе с ребейзом на upstream, а мажорные апгрейды — отдельными задачами. + +## Методика + +- Дата проверки: **2026-06-20**, ветка форка `feat/ai-agent-roles`. +- `pnpm outdated -r` (рекурсивно по воркспейсу: root `docmost`, `server`, `client`, + `@docmost/mcp`, `@docmost/editor-ext`). +- `pnpm audit --prod` (+ `--json`) — только прод-зависимости. +- Итог: **162** устаревших записи, из них **50** отстают на мажор и больше; + **51 уязвимость** (16 high / 26 moderate / 8 low). + +--- + +## 1. Безопасность — приоритет (51 уязвимость) + +### 1.1. Самый дешёвый фикс: `pnpm.overrides` пинят УЯЗВИМЫЕ версии + +В корневом `package.json` секция `pnpm.overrides` фиксирует ряд пакетов ровно на тех +версиях, на которые ругается `pnpm audit`. Достаточно поднять пины — код не трогаем. + +| override (текущий пин) | advisory | severity | поднять до | +|---|---|---|---| +| `ws: 8.20.1` | DoS из мелких фрагментов (`<8.21.0`) | **high** | `8.21.0+` | +| `undici: 7.24.0` | обход проверки TLS-сертификата (`<7.28.0`) | **high** | `7.28.0+` | +| `tmp: 0.2.6` | path traversal, обход `_assertPath` (`<0.2.7`) | **high** | `0.2.7+` | +| `hono: 4.12.18` | CORS отражает любой Origin с credentials (`<4.12.25`) | **high** | `4.12.25+` | +| `protobufjs: 7.5.8` | DoS через unbounded Any (`<=7.6.0`) | **high** | `7.6.3+` | +| `dompurify: 3.4.1` | мутация `allowedTags` в хуке (`<3.4.7`) | moderate | `3.4.11` | + +> Важно: `dompurify` — наш XSS-санитайзер, а override держит его на 3.4.1 (уязвимой), +> хотя в реестре уже 3.4.11. Это сводит на нет смысл санитайзера в части кейсов. + +### 1.2. Прямые зависимости — фикс бампом версии + +| пакет | у нас | где | advisory | severity | фикс | +|---|---|---|---|---|---| +| `@nestjs/platform-fastify` | `^11.1.19` (резолв 11.1.19) | server | обход middleware через trailing slash (`<=11.1.23`) | **high** | поднять lockfile до `11.1.27` | +| `nodemailer` | `^8.0.5` | server | `raw`-опция обходит `disableFileAccess` (`<=9.0.0`) | **high** | мажор `9.0.1` | +| `form-data` | `^4.0.0` (резолв 4.0.5) | @docmost/mcp | CRLF-инъекция (`<4.0.6`) | **high** | обновить lockfile до `4.0.6` | +| `react-router-dom` | `7.13.1` | client | произвольный контент через turbo-stream (`<=7.14.1`); CSRF на PUT/PATCH/DELETE (`<7.15.1`) | **high** + low | `7.15.1+` | + +> `@nestjs/platform-fastify`: middleware-bypass напрямую касается auth-цепочки — +> это самый «горящий» из прямых. Caret `^11.1.19` уже разрешает `11.1.27`, нужен +> только пересбор lockfile. + +### 1.3. Транзитивные (через зависимости) — фикс через override или бамп родителя + +- `fast-uri <=3.1.0` (**high**, path traversal) — через `fastify`. +- Прочие moderate, всплывающие транзитивно: `markdown-it <=14.1.1` (DoS), + `qs` (DoS), `uuid` (bounds check), `nanoid@^3` (предсказуемость), + `@opentelemetry/core` (unbounded memory), `undici` (cross-user disclosure), + `esbuild`/`@babel/core` (low, только dev-сервер/сборка). + +--- + +## 2. Очень старые — отставание на мажор (тех-долг) + +### 2.1. Рискованные мажоры — каждый отдельной задачей с тестированием + +| пакет | у нас | latest | замечание | +|---|---|---|---| +| `@mantine/*` 8 → 9 + `react`/`react-dom` 18 → 19 + `@types/react` 18 → 19 | 8.3.18 / 18.3.1 | 9.3.2 / 19.2.7 | Это апгрейд из upstream **PR #2293** (`chore: migrate to Mantine 9 and React 19`). Делать как у них: бамп + 3 паттерна (`useRef(undefined)`, обёртка `onChange`, шим `v8CssVariablesResolver`). Затрагивает в т.ч. EE-компоненты. | +| `@hocuspocus/{provider,server,transformer}` | 3.4.4 | 4.3.0 | Realtime-collab. Связано с `y-prosemirror`/`yjs` (на `yjs` уже есть патч `patches/yjs@13.6.30.patch` — учесть при бампе). upstream `main` тоже ещё на 3.x — координировать. | +| `@casl/ability` 6 → 7, `@casl/react` 5 → 7 | 6.8.0 / 5.0.1 | 7.0.0 | Библиотека прав доступа (авторизация) — мажор требует аккуратной проверки правил CASL. | +| `typescript` 5 → 6 | 5.9.3 | 6.0.3 | Мажор TS — глобально по трём пакетам, возможны новые ошибки типов. | +| `zod` 3 → 4 | 3.25.76 | 4.4.3 | В `@docmost/mcp`; zod 4 ломающий. Критично, т.к. zod описывает схемы инструментов AI/MCP (см. бэклог `ai-chat-tool-definitions-duplicated.md`). | +| `stripe` 17 → 22 | 17.7.0 | 22.2.2 | **+5 мажоров** (EE-биллинг). Если биллинг не используется — низкий приоритет, но разрыв самый большой. | + +### 2.2. Тулинг и прочие мажоры (рутинно, пачкой) + +`eslint` 9→10 + `@eslint/js` 9→10, `nx`/`@nx/js` 22→23, `i18next` 25→26 + +`react-i18next` 16→17 + `i18next-http-backend` 3→4, `undici` 7→8 (само приложение; +для security достаточно 7.28, мажор 8 — отдельно), `nodemailer` 8→9 (см. §1.2), +`marked` 17→18, `msgpackr` 1→2, `diff` 8→9, `concurrently` 9→10, +`@atlaskit/pragmatic-drag-and-drop*` 1→2/3 (DnD дерева), `react-clear-modal` 2→3, +`jsdom` 25/27→29 (dev/тесты), `@casl` (см. §2.1), плюс dev-types: +`@types/node`, `@types/nodemailer` 7→8, `@types/supertest` 6→7, `@types/yauzl` 2→3. + +--- + +## 3. Deprecated и несогласованность + +- **`@types/form-data` (2.5.2) — DEPRECATED.** Пакет `form-data` теперь поставляет + собственные типы. Зависимость в `@docmost/mcp` нужно **удалить**, а не обновлять. +- **`@types/node` рассинхронизирован по воркспейсу:** `@docmost/mcp` — 20.19, + `client` — 22.19, `server` — 25.5 (latest 26). Привести к единой мажорной линии + (по фактической версии Node в рантайме/Docker; в `package.json` поле `engines` + не задано — стоит зафиксировать). + +--- + +## 4. Рекомендованный порядок работ + +1. **Security-патч одной задачей (низкий риск):** поднять пины в `pnpm.overrides` + (§1.1) + пересобрать lockfile для caret-зависимостей (§1.2: fastify-platform, + form-data) + `react-router-dom` → 7.15.1 + `nodemailer` → 9. Прогнать + `pnpm audit --prod` до нуля high/critical. Убрать `@types/form-data`. +2. **Рутинные минор/патч-бампы** (большинство из 162) — пачкой вместе с + ближайшим ребейзом на upstream `docmost/main`. +3. **Мажоры из §2.1 — каждый отдельной веткой/задачей** с ручным тестом + соответствующей подсистемы (редактор, collab, права, i18n, AI-схемы). +4. Перепроверить, не конфликтуют ли бампы с локальными патчами + `patches/yjs@13.6.30.patch` и `patches/scimmy@1.3.5.patch` — при смене версии + путь патча (`yjs@13.6.30`) перестанет совпадать и `pnpm install` упадёт. + +## Оговорки + +- Снимок версий быстро устаревает — перед работой повторить `pnpm outdated -r` + и `pnpm audit --prod`. +- Многие «текущие» версии унаследованы от upstream; часть мажоров (Mantine9/React19, + Hocuspocus 4) upstream ещё не сделал — есть смысл дождаться/подсмотреть их подход, + чтобы не расходиться с веткой обновлений.