Избегайте внедрения команд с помощью API system()

Избегайте внедрения команд с помощью API system()

У нас есть устаревший код C, который позволяет менее привилегированным пользователям запускать пользовательские скрипты с повышенными привилегиями. Он имеет установленный бит SUID. Этот код ограничивает окружение PATH определенной папкой, а затем использует system()API для выполнения скрипта с ограниченной оболочкой:

/bin/bash -r -c "script <arg>"

Поскольку путь ограничен, можно выполнять только скрипты из этой конкретной папки.

Теперь, зная все подводные камни для внедрения команд с помощью system()API, какие меры можно предпринять, чтобы избежать внедрения команд? Это используется во многих местах в различных скриптах и ​​т. д., поэтому не хочется делать совершенно новую реализацию, чтобы избежать регрессии.

решение1

Поскольку это трудно сделать правильно, я бы предложил удалить SUID из вашего кода. Измените ваш код C, чтобы использовать sudo. Используя sudo, более сложные аспекты получения безопасного системного программирования выполнены.

Затем вы можете аккуратно создать конфигурацию sudo, используя visudo, которая делает минимум, необходимый для выполнения задачи, и ограничить его требуемыми пользователями/группами. После настройки sudo попросите кого-нибудь другого протестировать его и попытаться сломать предполагаемые ограничения.

решение2

Для внедрения кода требуется, чтобы пользователь мог передавать произвольные строки в качестве параметров вызова system(). Это очень похоже на SQL-инъекции и должно избегаться аналогичным образом: не передавайте никакие определяемые пользователем строки напрямую в вызов:

  • числовые параметры должны быть преобразованы в целые числа, а затем преобразованы обратно в строки во время вызова

  • параметры, принадлежащие фиксированному словарю, должны быть преобразованы в значения «enum» или аналогичные, а затем обратно в строки во время вызова

  • Свободный ввод текста должен быть ограничен безобидным набором символов, где это возможно (например, [a-zA-Z0-9]*). Там, где требуются проблемные символы (включая пробел), следует применять соответствующее экранирование (то есть a bзаменять на a\ b, и т. д.)

Связанный контент