Execute Command в n8n: когда нужен shell и как не открыть дыру в безопасности ¶
Обновлено: 2026-05-29
Execute Command node запускает shell-команду из workflow. Это мощно и опасно одновременно. С её помощью можно вызвать локальный скрипт, архиватор, ffmpeg, rclone, backup-команду или внутреннюю CLI-утилиту. Но если передать в команду пользовательский ввод без фильтрации, workflow может превратиться в удалённый запуск произвольных команд.
Не используйте Execute Command для обычного API
Если задача — сделать HTTP-запрос, используйте HTTP Request. Если задача — обработать JSON, используйте Code node. Execute Command оставляйте для сценариев, где действительно нужен инструмент операционной системы.
Когда Execute Command уместен ¶
| Сценарий | Подходит? | Комментарий |
|---|---|---|
| Запустить backup-скрипт | Да | если команда фиксированная и не строится из пользовательского ввода |
| Конвертировать файл через ffmpeg | Да, осторожно | нужны ограничения путей, размера и формата |
| Сделать curl к API | Нет | лучше HTTP Request node |
| Выполнить пользовательскую строку как команду | Нет | это риск shell injection |
| Запустить внутреннюю CLI с allowlist аргументов | Иногда | если команда ограничена и логируется |
Главный риск: shell injection ¶
Опасный вариант выглядит так: workflow принимает поле filename из webhook и подставляет его в команду. Пользователь может передать строку с ;, && или подстановкой shell. Даже если сервис внутренний, payload может прийти из формы, CRM, Telegram или email.
# Плохо: аргумент строится из внешнего ввода без allowlist
convert {{ $json.filename }} output.pdf
Безопаснее заранее выбирать действие из allowlist, а файлы хранить под внутренними именами, которые генерирует сам workflow.
Как проектировать безопасную команду ¶
- Команда должна быть фиксированной или почти фиксированной.
- Аргументы должны проходить allowlist: формат, расширение, длина, каталог.
- Пути должны вести только в рабочую директорию, например
/data/jobs/<job_id>. - Не передавайте токены в командной строке, если их можно прочитать через process list.
- Ограничьте размер stdout: большие выводы могут сломать execution.
- Пишите короткий лог: job_id, exit code, stderr summary.
Docker и отсутствующие команды ¶
Если n8n запущен в Docker, команда выполняется внутри контейнера n8n, а не на хосте. Поэтому привычные утилиты могут отсутствовать: curl, ffmpeg, python, rclone, ssh. Правильный путь — собрать отдельный образ на базе n8n и установить только нужные пакеты. Не ставьте внутрь контейнера всё подряд “на всякий случай”.
FROM docker.n8n.io/n8nio/n8n
USER root
RUN apk --update add ffmpeg
USER node
stdout maxBuffer и большие файлы ¶
Execute Command возвращает stdout/stderr в execution. Если команда печатает слишком много, можно получить ошибку buffer. Не выводите большие JSON, base64-файлы или длинные логи в stdout. Для больших результатов пишите файл в рабочую директорию, затем передавайте путь следующей ноде или используйте Read/Write File From Disk.
Права и окружение ¶
n8n обычно работает не от root-пользователя. Это хорошо. Не повышайте права только потому, что команда не запустилась. Сначала проверьте:
- есть ли бинарник в
PATH; - может ли пользователь n8n читать и писать нужную папку;
- смонтирован ли volume в контейнер;
- не блокирует ли команду sandbox/политика хостинга;
- не пытаетесь ли вы обратиться к файлам хоста, которых нет в контейнере.
Нормальный паттерн: wrapper script ¶
Для production лучше не собирать длинную shell-команду в поле ноды. Создайте wrapper script, который принимает ограниченный набор аргументов, сам валидирует вход и возвращает понятный JSON-результат.
#!/usr/bin/env sh
set -eu
JOB_ID="$1"
case "$JOB_ID" in
''|*[!a-zA-Z0-9_-]*) echo '{"ok":false,"error":"bad_job_id"}'; exit 2 ;;
esac
# безопасная работа только внутри /data/jobs/$JOB_ID
В workflow тогда вызывается не произвольная команда, а конкретный скрипт с понятным контрактом.
Частые ошибки ¶
| Симптом | Причина | Решение |
|---|---|---|
/bin/sh: command not found | команды нет в Docker image или PATH | собрать кастомный image или заменить на ноду n8n |
permission denied | нет прав на файл или скрипт | проверить owner, chmod, volume и пользователя контейнера |
stdout maxBuffer exceeded | команда выводит слишком много | сократить вывод, писать результат в файл |
| на локальной машине работает, в n8n нет | разное окружение: Docker, PATH, env, user | проверить команду внутри контейнера |
| случайные падения | нет timeout/lock, команда конкурирует за файл | добавить job_id, временные папки и блокировки |
Что использовать вместо Execute Command ¶
- HTTP Request — для API и curl-сценариев.
- Code node — для JSON и лёгкой логики.
- Convert to File / Extract from File — для файловых операций, если не нужен shell.
- Task runners — когда нужен контролируемый запуск кода в self-hosted окружении.
- Security checklist — если workflow работает с секретами и файлами.