Як безпечно передавати змінні сценаріям із включеним root?


13

Це питання є загальним і не стосується лише моєї ситуації, але ... У мене є невеликий пристрій для зайнятих ящиків, де я хочу, щоб користувач, який не має root, мав змогу виконувати певний скрипт із root правами. Наприклад, щось на зразок цього невеликого сценарію для включення DHCP, де єдиною змінною ( $1) для надсилання на cmdline (!!) є те, що ім'я хоста надсилати:

#!/bin/bash
udhcpc -b -i eth0 -h $1

як працює такий udhcpc, потрібен кореневий доступ, тому для цього я планую змінити, /etc/sudoersщоб містити цей рядок:

joe ALL = NOPASSWD: /path/to/enable_dhcp.sh

який повинен дозволити "joe" легко запускати цей скрипт з привілеями root, просто запустивши:

sudo /path/to/enable_dhcp.sh

і не запитувати пароль (що я хочу, оскільки я хочу, щоб Джо міг це сценарій).

Тепер я знаю (або, принаймні, думаю, що я роблю), що використання $1в скрипті, який можна легко запустити з привілеями root, - ХОРОБА ідея, оскільки ви можете вводити в це все, що хочете.

Отже ... який найкращий спосіб впоратися з цим? Як я можу дозволити Джо робити те, що я хочу з привілеями root, дозволити йому переходити в змінну (або ефективно робити так, як із змінною оточення), не будучи широко відкритим для ін'єкційних атак?

Відповіді:


14

Запуск скриптів оболонки в розділі " sudoБезпечно" за умови sudoналаштування для скидання середовища . І навпаки, якщо sudoне скидає середовище, запуск сценарію оболонки не є безпечним, навіть якщо ваш скрипт не використовує його параметри (див. Дозволити встановлення сценаріїв оболонок ). Переконайтеся , що у вас є Defaults env_resetв /etc/sudoersабо що цей параметр під час компіляції по замовчуванням ( sudo sudo -V | grep envповинен включати Reset the environment to a default set of variables).

Особливої ​​небезпеки при використанні параметрів скрипту немає. $1це рядок, все, що вам потрібно переконатися, це те, що ви використовуєте його як рядок. (Наприклад, не робіть eval "$1".) Очевидно, що тут особливо важливо не робити припущень щодо вмісту змінної, а ставити подвійні лапки навколо всіх змінних підстановок (тобто писати "$1", ні $1). Зауважте, що розміщення подвійних лапок навколо змінних підстановок не характерне для сценаріїв, що працюють з привілеями, це потрібно робити постійно.

Ви можете додатково перевірити параметр, залежно від того, що udhcpcвідбувається з тим, що не схоже на ім'я хоста. Наприклад, це здійснить першу синтаксичну перевірку:

#!/bin/sh
case "$1" in
  *[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;;
esac
udhcpc -b -i eth0 -h "$1"

Інші речі, які слід врахувати, що можуть вплинути на поведінку цієї команди: поточний робочий каталог та те, на що вказують stdin, stdout, stderr, обробники сигналів та обмеження. Наприклад, дозволяючи базові дампи (після <kbd> Ctrl- \ </kbd>), ви можете дозволити користувачеві засмічувати / запускати / блокувати, що в моїй системі є tmpfs з дуже обмеженим розміром і може дозволити DoS.
Стефан Шазелас

5

Ви повинні відповідати пройденому входу проти відомого хорошого шаблону.

Наприклад, схоже, що IP-адреса може бути для вас правильним вводом. Отже, ви можете використовувати щось подібне:

if [[ "$1" =~ ^[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9]$ ]]
then
  udhcpc -b -i eth0 -h "$1"
else
  echo "Don't mess with me pork chop."
fi

Зауважте, що regexp не перевірена, ви несете відповідальність за те, щоб ваш regexp не допускав нічого небезпечного.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.