OpenCode — популярный opensource AI-агент для кодинга с 161k звёзд на GitHub. Его суть — скормить LLM-модели команду вроде llm | bash, а дальше он сам читает файлы, пишет код, запускает shell. Проблема в том, что этот «bash» практически не защищён.
Начать стоит с того, что OpenCode по умолчанию тянется к удалённой модели. Если вы не настроили локальную — он просто соединяется с сервером models.dev, даёт ему доступ к вашей файловой системе и ждёт первого ввода. Нажали Enter — модель уже читает ваш проект и отправляет содержимое наружу. Всё это без единого предупреждения.
Фильтрация bash-команд — отдельный цирк. В opencode.json можно прописать "git *": "deny". Но это работает только если команда написана в лоб. echo 'git clean -fdx .' | bash проходит на ура. base64 декод с git push --force — тоже. OpenCode парсит bash через tree-sitter AST и проверяет только прямые вызовы. Всё, что обёрнуто в python3 -c, bash <<EOF или alias, игнорируется. Список команд, для которых вообще проверяются пути к файлам, жёстко захардкожен. echo там нет, поэтому echo 1 > /sys/class/gpio/export пройдёт без вопросов. При этом echo часто разрешают навсегда, и потом через него можно делать что угодно.
Файловые разрешения тоже сломаны. Если вы сказали «Always» для echo, то любая команда с echo разрешена. Даже echo Z2l0... | base64 -d | bash. А проверка путей в bash AST не ловит редиректы — они висят как sibling-узлы, а проверяются только внутри command.
Кроме того, OpenCode умеет сам себя обновлять через curl https://opencode.ai/install | bash. Прямо в production-коде. Уже был CVE, когда включённый по умолчанию HTTP-сервер с CORS разрешал любому сайту на порту отправлять shell-команды на вашу машину. Разработчики пофиксили, отключив сервер по умолчанию, но дыра в архитектуре осталась.
В итоге: запрет на git можно обойти сотней способов, файлы вне проекта читаются через python3, а защита основана на текстовом AST-парсинге, который не видит ни редиректов, ни каналов, ни вложенных оболочек. Вывод из статьи один: OpenCode использовать не стоит.