Почему POSIX wordexp(3) опасен для недоверенных данных

· Безопасность
Функция wordexp(3) из POSIX, которую часто советуют для раскрытия тильды, по умолчанию выполняет и подстановку команд — а флаг WRDE_NOCMD спасает не всегда.

cover.svg

Функцию wordexp(3) из стандарта POSIX нередко рекомендуют как удобный способ выполнить в программе на C раскрытие в стиле оболочки — например, превратить ~/foo в /home/me/foo. Код выглядит невинно: вызываете wordexp(), забираете первый элемент we_wordv, освобождаете память через wordfree(). Для раскрытия тильды этого достаточно.

Проблема в последнем аргументе — наборе флагов. По умолчанию, когда там стоит 0, включены все возможности раскрытия, в том числе подстановка команд. А это значит, что строка вроде $(whoami)/foo или $(cat /etc/passwd)/foo, попавшая на вход, будет честно выполнена оболочкой. Безобидная «утилита для разворачивания путей» превращается в исполнение произвольных команд.

WRDE_NOCMD помогает не везде

Казалось бы, лекарство есть: флаг WRDE_NOCMD, который должен запретить подстановку команд. Но автор предупреждает, что в некоторых реализациях libc это в лучшем случае полумера.

Библиотека musl реализует wordexp(3), попросту делегируя работу системной оболочке. Перед этим она пытается бегло просканировать строку на предмет подстановок команд, но её проверка неполна: некоторые конструкции, которые нижележащая оболочка (например, GNU Bash) считает корректной подстановкой, musl пропускает мимо.

macOS устроена похоже: её libc перекладывает работу на вспомогательный процесс /usr/lib/system/wordexp-helper. По словам Джулиана Сквайрса, ещё в 2023 году здесь работал тот же обход, что и в musl. Автор, впрочем, не стал проверять, актуален ли он сегодня, когда оболочкой по умолчанию в macOS стала zsh вместо bash. (Любопытная деталь: прежде wordexp(3) в macOS вызывал Perl — wordexp-helper выглядит как «современная» замена.)

Вывод

Не применяйте wordexp(3) к недоверенным данным — даже с флагом WRDE_NOCMD. Если нужно всего лишь раскрыть тильду, разумнее сделать это вручную, не отдавая строку на откуп оболочке.


Источник: Lobsters

Комментарии

Войдите, чтобы комментировать.

  • Пока нет комментариев.