[1] critical Файл: ai-review.js:865-883 Тип: security Описание: `setupCodexCLIEnvironment` десериализует весь объект с `access_token`/`refresh_token` и прямо пишет его в `~/.codex/auth.json` с дефолтными правами доступа, не очищает файл и не ограничивает доступ, поэтому любой процесс/пользователь на той же машине может прочитать токены и использовать их. Кроме того, файл формируется из переменных окружения без шифрования, что делает утечку конфиденциальной информации тривиальной. Решение: сохранять ключи только в защищённом хранилище (например, `ssm`, `vault` или `process.env`), если нужно — записывать на диск с явно заданными правами доступа (`mode: 0o600`) и удалять после выполнения, либо передавать в Codex CLI через stdin вместо создания постоянного файла. [2] critical Файл: ai-review.js:1200-1283 Тип: security Описание: `saveReportToServer` держит SSH-пароль в `CONFIG.sshPassword`, простым текстом подставляет его в команды `sshpass -p "..."` и запускает `ssh`/`scp` через `execSync`. Пароль появляется в списке процессов, логах и может быть захвачен любым пользователем на хосте. Кроме того, отсутствует проверка и экранирование входных данных в интерполированные команды. Решение: перейти на SSH-ключи/агент, привязанные к учетной записи, или хотя бы читать пароль из защищенного файла и передавать через stdin, избегая `sshpass` и кавычек в командной строке; также применять `child_process.spawn` с аргументами вместо оболочки и не хранить секреты в переменных окружения общего доступа. [3] major Файл: ai-review.js:108-140 Тип: performance Описание: `downloadFile` накапливает весь ответ в памяти через `Buffer.concat` и затем вызывает `fs.writeFileSync`, без лимитов по `Content-Length`, таймаутам или streaming. При указании `CONFIG.deepseekPromptUrl` на большой или медленно отзывающийся ресурс можно быстро исчерпать оперативную память и заблокировать процесс. Решение: использовать потоковое копирование `response.pipe(fs.createWriteStream(outputPath))`, проверять `content-length`/время ожидания и при превышении ограничения прерывать загрузку (с `req.destroy()`), а также устанавливать разумные таймауты на соединение/чтение. [4] major Файл: src/app/api/projects/[id]/figma-links/route.ts:72-178 Тип: performance Описание: `refreshPreviewInBackground` загружает Figma metadata, логирует размер, но несмотря на предупреждение о `responseSizeMB > 50`, всегда вызывает `metadataResponse.json()`, копируя весь ответ в память. Запросы к оригинальным Figma-файлам могут быть сотни мегабайт, что приводит к OOM/GC-падам (об этом свидетельствует блок `catch` ниже). Решение: использовать `AbortController`/`ReadableStream`, проверять `content-length` и отменять запрос до парсинга, ограничивать обрабатываемый объём (например, считывать только первые N байт и валидировать вручную) или запрашивать облегчённый endpoint (`/meta`) сразу, чтобы не держать большой JSON в памяти. [5] major Файл: src/app/api/projects/[id]/figma-links/route.ts:200-230 Тип: security Описание: `POST`-эндпоинт проверяет только `requireRequestAuth` и роль `PROJECT_MANAGER`, но не удостоверяется, что текущий пользователь связан только с указанным `projectId`. Любой менеджер может отправить запрос с произвольным `id` и добавить/перезаписать ссылки чужого проекта. Это позволяет модифицировать проекты сторонних команд и нарушает границы данных. Решение: до создания ссылки проверять, что `auth.userId` связан с проектом (через таблицу `project.managerId` или `members`), и только после этого позволять вставку; либо использовать scoped роли/политику, а не глобальную роль.