22.3.3. Переменные окружения
22.3.3. Переменные окружения
В программах, работающих с возможностями setuid или setgid, нужно проявлять особую осторожность с установками окружения. Эти переменные определяются пользователем, активизировавшим программу, тем самым открывается путь для атак. Самая явная атака может пройти через переменную окружения PATH, изменяющую те каталоги, в которых функции execlp() и execvp() отыскивают программы. Если привилегированная программа запускает другие программы, то она должна убедиться, что это именно те программы, которые нужны! Пользователь, который имеет возможность подменить программный путь поиска, легко может подвергнуть программу опасности.
Существуют и другие переменные окружения, которые могут оказаться опасными. Например, переменная LD_PRELOAD позволяет пользователю указать некоторую библиотеку для загрузки до стандартной библиотеки С. Это может быть полезным, но одновременно и очень опасным в привилегированных приложениях (по этой же причине переменная окружения игнорируется, если реальное и эффективное универсальные имена совпадают).
Если программа локализована, то переменная NLSPATH также становится проблемной. Она позволяет пользователю переключать используемый программой языковой каталог, который определяет способ перевода строк. Это означает, что в переводных программах пользователь имеет возможность указать значение для любой переводимой строки. Строку можно сделать сколько угодно длинной, вынуждая программу быть крайне осторожной при выделении буфера. Еще более опасным является то, что при переводе форматирующих строк для таких функций, как printf(), можно изменить формат. Например, строка Hello World, today is %s может превратиться в Hello World, today is %c%d%s. Трудно предсказать, какое воздействие могут оказать подобные изменения на функционирование программы!
Все это сводится к тому, что наилучшим решением для переменных окружения setuid- или setgid-программ является исключение этих переменных. Функция clearenv()[163] стирает все значения из окружения, оставляя его пустым. После этого программа может заполнить любые необходимые ей переменные окружения известными значениями.