Files
gitmost/docs/backlog/dependency-updates-and-security-audit.md
glm5.2 agent 180 ddfccb30f3 docs(backlog): add dependency update & security audit snapshot
Record outdated-deps and security-audit findings for the fork as of
2026-06-20 (pnpm outdated -r + pnpm audit --prod): 162 outdated entries,
50 major-behind, 51 vulnerabilities (16 high).

Key finding: pnpm.overrides pin several packages to versions flagged by
the audit (ws, undici, tmp, hono, protobufjs, dompurify) — cheapest fix
is bumping the pins. Also flags direct-dep highs (@nestjs/platform-fastify
auth middleware bypass, nodemailer, form-data, react-router-dom),
risky majors to schedule separately (Mantine9/React19, Hocuspocus 4,
CASL 7, TypeScript 6, zod 4, stripe), the deprecated @types/form-data,
and @types/node drift across the workspace.
2026-06-20 15:43:23 +03:00

118 lines
9.1 KiB
Markdown

# Обновление зависимостей: устаревшие версии и аудит безопасности
Статус: **зафиксировано в беклоге, зависимости не менялись.** Это снимок состояния
на дату проверки — список задач на обновление, а не баг. Бо́льшая часть версий
**унаследована от 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 ещё не сделал — есть смысл дождаться/подсмотреть их подход,
чтобы не расходиться с веткой обновлений.