如何安全地將變數傳遞給啟用 root 的腳本?
這個問題是完全一般的,不僅適用於我的情況,而且……我有一個小型的busybox設備,我希望非root使用者能夠執行具有root權限的特定腳本。例如,類似這個啟用 DHCP 的小腳本,其中
$1
要在 cmdline (!!) 上發送的唯一變數 () 是要發送的主機名:#!/bin/bash udhcpc -b -i eth0 -h $1
像這樣執行 udhcpc 需要 root 訪問權限,因此我計劃修改
/etc/sudoers
以包含此行:joe ALL = NOPASSWD: /path/to/enable_dhcp.sh
這應該使“joe”能夠通過簡單地執行以root權限輕鬆執行該腳本:
sudo /path/to/enable_dhcp.sh
並且不會被要求輸入密碼(這是我想要的,因為我希望 joe 能夠編寫此腳本)。
現在..我知道(或者至少我認為我知道)
$1
在可以輕鬆以 root 權限執行的腳本中使用是一個可怕的想法,因為您可以將任何您想要的東西注入其中。那麼……處理這個問題的最佳方法是什麼?我如何讓 joe 使用 root 權限做我想做的事,允許他傳入一個變數(或者像使用環境變數一樣有效地這樣做),同時不對注入攻擊敞開大門?
在配置為重置環境的情況下執行 shell 腳本
sudo
是安全的sudo
。相反,如果sudo
不重置環境,則執行 shell 腳本是不安全的,即使您的腳本不使用其參數(請參閱允許 shell 腳本上的 setuid)。確保你有Defaults env_reset
in/etc/sudoers
或者這個選項是編譯時預設的(sudo sudo -V | grep env
應該包括Reset the environment to a default set of variables
)。使用腳本參數沒有特別危險。
$1
是一個字元串,您需要確保將它用作字元串。(例如,不要這樣做eval "$1"
。)顯然,這里特別重要的是不要對變數的內容做出假設,並且在所有變數替換(即 write , not )周圍加上雙引號。請注意,在變數替換周圍加上雙引號並不特定於以特權執行的腳本,而是您必須一直做的事情。"$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"