ルートサポートスクリプトに変数を安全に渡すには?

ルートサポートスクリプトに変数を安全に渡すには?

この質問は完全に一般的なものであり、私の場合にのみ適用されるものではありません。私は小さなビジボックスデバイスを持っていて、root以外のユーザーがroot権限で特定のスクリプトを実行できるようにしたいです。たとえば、DHCP を有効にする次のような小さなスクリプトがあります。ここで$1cmdline(!!) に送信される唯一の変数は、転送するホスト名です。

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

/etc/sudoersudhcpcをこのように実行するにはrootアクセスが必要なので、次の行を含めるように変更する予定です。

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

これにより、「joe」は以下を実行してroot権限でスクリプトを簡単に実行できます。

sudo /path/to/enable_dhcp.sh

そしてパスワードを聞かないでください(私はJoeがこのスクリプトを書くことができるようにしたいので、パスワードが欲しいです)。

今私知る(または少なくとも私の考えでは)$1root権限で簡単に実行できるスクリプトで使用するのは恐ろしいアイデアです。欲しいものは何でも挿入できるからです。

だから...この問題を処理するための最良の方法は何ですか?注入攻撃に対して脆弱ではなく、Joeがroot権限で目的の操作を実行して変数を渡すことができるようにする(または環境変数を使用するのと同じくらい効率的に)、どうすればよいですか?

ベストアンサー1

以下のシェルスクリプトを実行するのはsudo安全です前提は、sudo環境をリセットするように構成されていることです。。逆に、sudoスクリプトが引数を使用しなくても環境をリセットせずにシェルスクリプトを実行するのは安全ではありません(参照:シェルスクリプトでsetuid設定を許可する)。このオプション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"

おすすめ記事