Subject: How can I get setuid shell scripts to work? Date: Thu Mar 18 17:16:55 EST 1993
まず、読者がいわゆる「実行可能シェルスクリプト」を認識するUNIX種 (例え ば、4.3BSDとかSunOS) を使っていると仮定します。そのようなスクリプトは 次のような行で始まっているでしょう。
#!/bin/shこのようなスクリプトはいわゆる「マジックナンバ」(実行形式の種類を示す) ではじまる本物の (バイナリ) 実行形式に似ているため、「実行形式である」 といわれます。この場合、マジックナンバは '#!'で、OSは最初の行の '#!' 以降をスクリプトのインタプリタ (1文字のオプションが続くことがあります) であると解釈します。以下に例を示します。
#!/bin/sed -fこの例で挙げた上記の行で始まるスクリプトを 'foo' と呼ぶことにしましょう。 このスクリプトは /bin にあるとします。ここで、次のように入力した場合に ついて考えます。
foo arg1 arg2 arg3OS はこの入力を、以下のような入力があった、というように再配列します。
/bin/sed -f /bin/foo arg1 arg2 arg3しかしながら、一つ違いがあります。'foo' の setuid 許可ビットが設定され ている場合、すなわち第一番目の例では、コマンド(foo)の許可ビットに従うこ とになります。もし、2番目のように実際に入力したときには、OSは /bin/sed の許可ビットに従います。当然ながら、/bin/sed は setuid されていません。
---------- さて次に、もしシェルスクリプトが '#!' 行で始まっていない場合、もしくは OS が '#!' を認識していない場合はどうなるでしょう。
この場合には、ファイルが正当なマジックナンバーで始まっていないないため、 シェル(か他のプログラム)がスクリプトを実行しようとした時OSがエラーを返 します。シェルはこのエラーを受け取ると、当該ファイルがシェルスクリプト であると「仮定」しまして、以下のような実行をしてみます:
しかしながら、上述のようにこの場合には 'shell_script' に対する setuid ビットは効力を発揮しません。
---------- さて、次に setuid シェルスクリプトがセキュリティ上、危ない点について述 べましょう。
'/etc/setuid_script' というスクリプトが以下のように始まっているとします。
#!/bin/shここで、次のような順序でコマンドを実行したら何が起こるでしょうか。
$ cd /tmp $ ln /etc/setuid_script -i $ PATH=. $ -i最後のコマンドが以下のようになるのは上述の通りです。
/bin/sh -iこのコマンドはスクリプトの持ち主に setuid された、インタラクティブな シェルを起動することになります!まあ、このセキュリティホールは第一行を 次のようにすることで簡単に塞ぐことが出来ます。
#!/bin/sh -'-' はオプション列の終りを示します。次の引数の '-i' は本来そうあるべき であるように、コマンド群を読み込むべきファイル名として解釈されます。
--------- しかしながらもっと重大なセキュリティに関する問題があります。
$ cd /tmp $ ln /etc/setuid_script temp $ nice -20 temp & $ mv my_script temp3番目のコマンドは次のように解釈されます。
nice -20 /bin/sh - tempnice をかけることで、コマンドの実行をずっと遅くできるので、'temp' を シェルが読み込む「前」に4番目のコマンドによりもともとの 'temp' を 'my_script' に置き換えることが可能です。このセキュリティホールを塞ぐ には以下の4つの方法があります。
#!/bin/indir -u #?/bin/sh /etc/setuid_script
そうです!シェルスクリプト中で、PATH 変数に安全なパスを明確に指定するこ とを忘れてはいけません。何故だかわかりますか。これとは別に適切に設定さ れていないと面倒を引き起こし得る IFS という変数もあります。他にも、同様 にセキュリティの低下に影響する環境変数がいくつかあります。例えば、SHELL 等です。更に、スクリプト中のコマンド群が対話シェルエスケープを許してい ないことを確認しなければなりません!そして、変に設定されているかも知れ ない umask という値があります...
その他諸々。で、setuid スクリプトはスクリプト中で呼び出すすべてのコマン ドのバグとセキュリティに関する危険を「受け継ぐ」ということを肝に命じて おいて下さい!
概して、setuid シェルスクリプトは非常に危険なものであるということがおわ かり頂けたと思います。かわりに C のプログラムを書く方がより良い解決にな るでしょう。