Найдите уязвимость в bash-скрипте deploy.sh, где используется ssh user@host "rm -rf $DIR/*" при ненадёжной переменной DIR — объясните риск и как безопасно обрабатывать параметры и кавычки

16 Фев в 11:41
23 +1
0
Ответы
1
Коротко — в чём уязвимость
- Команда в скрипте: `ssh user@host "rm -rf $DIR/*"` опасна потому, что значение переменной `DIR` подставляется в команду, которая затем интерпретируется удалённой оболочкой. При пустой или некорректной `DIR` вы легко получите удаление корня (`rm -rf /*`) или возможность инъекции команд (символы `;`, `&`, `` ` ``, `$(...)` и т.п. в значении переменной могут изменить удалённую команду).
Риски
- Если `DIR` пустая → удалится `/*`.
- Если `DIR` начинается с `-` → может быть интерпретировано как опция `rm` (решается `--`).
- Если `DIR` контролируется извне → возможна удалённая команда-инъекция.
Как безопасно — правила и примеры
1) Всегда проверяйте и валидируйте `DIR` перед удалением:
- не пустая, не равна `/`, не указывает выше ожидаемой директории, подходит под ожидаемый шаблон.
Пример проверок:
```
[ -n "$DIR" ] || { echo "DIR empty, abort"; exit 1; }
case "$DIR" in
/|/*) echo "Refusing to operate on root or absolute-wildcard"; exit 1;;
esac
```
2) Используйте `--` для прекращения разбора опций:
```
rm -rf -- "$DIR"/*
```
3) Не подставляйте необработанную переменную напрямую в двойные кавычки SSH-команды. Надёжный шаблон — передать значение как аргумент в удалённый bash (через stdin), тогда значение не будет интерпретировано локальной/удалённой оболочкой:
```
ssh user@host 'bash -s' -- "$DIR" <<'BASH'
DIR="$1"
[ -n "$DIR" ] || { echo "DIR empty"; exit 1; }
case "$DIR" in /) echo "Refuse root"; exit 1;; esac
# удалить все (включая dotfiles)
shopt -s dotglob 2>/dev/null || true
rm -rf -- "$DIR"/* 2>/dev/null
BASH
```
Объяснение: `"$DIR"` передаётся как позиционный аргумент `$1` в удалённый `bash`. Здесь вы можете безопасно валидировать и затем вызвать `rm -rf -- "$DIR"/*`.
4) Альтернатива — эскейпить значение для bash с `printf '%q'` (только если удалённая оболочка — bash):
```
esc=$(printf '%q' "$DIR")
ssh user@host "rm -rf -- $esc/*"
```
(но этот метод требует аккуратности и совместимости; предпочтительнее передача как аргумента, см. пункт 3).
5) Лучше избегать `rm -rf` вообще, когда можно:
- использовать rsync/ssh и удаление через find с явными проверками: `find "$DIR" -mindepth 1 -delete`
- или удалить конкретные ожидаемые подкаталоги по списку.
Краткие рекомендации
- Проверяйте: не пусто, не `/`, находится в допустимой области.
- Всегда использовать `--` перед путём.
- Не выполняйте удаление на основе неэкранированных строк, поступивших извне; передавайте значения как аргументы удалённой программе (см. `ssh user@host 'bash -s' -- "$DIR"`).
- По возможности избегайте прямой подстановки в командную строку — эскейпьте/валидируйте.
16 Фев в 11:47
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир