[1] major Файл: ai-review.js:95-126 Тип: error-handling Описание: `downloadFile` читает файл по HTTP без таймаута и без учёта потоковых ошибок: `protocol.get` не ограничивает время выполнения, поэтому зависшие соединения или медленные ответы виснут до бесконечности, а также нет обработки `response.on('timeout')`/`req.setTimeout`. Это критично для CI, потому что один зависший промпт блокирует весь рабочий процесс и нельзя восстановиться. Решение – явно ставить таймаут (`request.setTimeout`) и слушать `timeout`/`socket` события, а также отлавливать `response.on('aborted')`/`'error'`, чтобы вовремя откатывать частично записанный файл (уже используется очистка). Можно также использовать `fetch`/`axios` с таймаутами и резидентным ограничением размера. [2] critical Файл: ai-review.js:322-374 Тип: security Описание: `isLocalFile` и `getChangedFiles` используют `execSync` со строковыми шаблонами (`git ls-files ... "${filePath}"`, `git diff ... origin/${targetBranch}...HEAD`, `git diff ... ${beforeSha}...${currentSha}`) без экранирования. `execSync` запускает `/bin/sh`, и если переменные (`filePath`, `targetBranch`, `beforeSha`, `currentSha`) содержат `"`/`;`/`&`, они могут сломать команду или выполнить дополнительный код. Эти значения поступают из CI-переменных и названий файлов, которые могут контролироваться пользователями (например, когда код мокается или ветка называется нестандартно). Следует перейти на `child_process.execFile`/`spawn` с аргументами вместо строки или явно экранировать входные значения перед подстановкой, а для файла — проверять, что он не содержит символов кавычек. [3] major Файл: ai-review.js:416-447 Тип: performance Описание: При построении промпта (`buildFilesContentPrompt`) весь файл во всех `changedFiles` читается целиком, а содержимое удерживается в памяти. В репозиториях с большими изменениями (images, генераторы, старыми бинарями) это может легко достичь десятков мегабайт и привести к OOM в CI. Желательно ограничить размер одного файла (например, 1‑2 МБ) и общий объём (не более N символов), пропуская бинарные файлы и добавляя лог о пропущенных. Альтернатива — стримить часть файла, а не держать целиком. [4] major Файл: ai-review.js:890-905 Тип: security Описание: `setupCodexCLIEnvironment` записывает токены `authData` в `~/.codex/auth.json` с дефолтными правами (пользовательские/групповые `rw`). В многоарендной среде CI/runner другие пользователи могут прочитать файл и похитить токены. Нужно либо использовать `fs.writeFileSync(path, data, { mode: 0o600 })`, либо помещать файл в директорию, доступ к которой ограничен и удаляется сразу после использования, а сам JSON не должен содержать лишней чувствительной информации. [5] major Файл: ai-review.js:1292-1334 Тип: security Описание: `saveReportToServer` формирует команды `sshpass -p "${CONFIG.sshPassword}" ssh ...` и `scp` для передачи отчёта. Пароль передаётся прямо в командной строке, попадая в `ps`/журналы и в вывод пайплайна, что вытягивает секреты в любой лог, где отображается `sshpass`. Вместо этого следует использовать SSH-ключи (`ssh-agent`/`~/.ssh`), либо передавать пароль через stdin (`sshpass -p` опция плоха) и принцип “ничего чувствительного в args”. Также желательно убрать пароль из логов и не выводить полные команды (в текущем коде всё логируется).