Тильда в PATH — это не всегда ваш домашний каталог
Автор возился с инструментом для песочницы агентов nono и получил от него подозрительное предупреждение: песочница может писать в элемент PATH ~/.local/bin/. Разбирательство привело к давней ловушке оболочки, о которой стоит знать каждому, кто правит свои .bashrc или .zshrc.
В чём подвох
Строка вида
export PATH="$PATH:~/.local/bin/"
не превратит тильду в путь к домашнему каталогу. Раскрытие тильды в $HOME происходит только для неэкранированных символов, а внутри двойных кавычек тильда остаётся самой собой. В итоге в PATH добавляется не /home/<user>/.local/bin/, а буквальный ./~/.local/bin/ — относительный путь к каталогу с именем «тильда» в текущей директории.
Документация bash это подтверждает: тильда-префикс раскрывается, если слово начинается с неэкранированной тильды, в том числе сразу после = или : в присваивании переменной. Ключевое слово — «неэкранированной».
Почему это небезопасно
Автор приводит наглядную демонстрацию. Он создаёт каталог ./~/.local/bin/, кладёт туда скомпилированный бинарник kek, а затем запускает PATH="~/.local/bin/" kek — и программа находится и выполняется. Домашний каталог при этом вообще не задействован: оболочка нашла исполняемый файл в подкаталоге текущей директории.
Отсюда и тревога песочницы: если в PATH оказывается элемент, относящийся к текущему каталогу, любой, кто сможет туда что-то записать, фактически получает возможность подсунуть вам исполняемый файл.
Как проверить и починить
Быстрая проверка:
echo "$PATH" | grep -- '~'
или, чтобы видеть каждый элемент отдельной строкой:
echo "$PATH" | tr ':' '\n' | grep '~'
Если что-то выводится — пора заглянуть в .bashrc, .zshrc или .profile и заменить тильду на $HOME:
export PATH="$PATH:$HOME/.local/bin/"
Любопытно, что вариант без кавычек — export PATH=$PATH:~/.local/bin — в bash и zsh всё-таки работает, потому что тильда раскрывается в присваиваниях после = и после каждого :. Но полагаться на это хрупко: достаточно пробела, и присваивание сломается. Автор отдельно поблагодарил инструмент nono за предупреждение — и пообещал прислать PR, чтобы сделать его сообщение чуть подробнее.
Источник: Hacker News
Комментарии
Войдите, чтобы комментировать.