web-dev-qa-db-ja.com

rootユーザーとして、phpからシェルスクリプトを実行しますか?

PHPから次の行を実行する必要があります。

$ res = Shell_exec( 'Sudo sh /home/nicklas/cronjobs/make_account.sh username password');

問題は実行時に何も起こらないことです。 $ resをエコーし​​ようとすると、空白になります。私もsystem()を使用してみましたが、同じ結果です。 rootアクセスでスクリプトを実行する必要があるため、機能しないと思います。www-dataユーザーには、デフォルトではそれがありません。アクセスを得るために、次の行を/ etc/sudoersに追加しました。

www-data ALL =(ALL:ALL)NOPASSWD:/home/nicklas/cronjobs/make_account.sh

しかし、成功しませんでした。その間にApacheを再起動してみましたが、何も変わりません。

私は何かを逃していますか?

5
qwerty

セキュリティ上の理由から、ユーザーwww-dataを使用して、本来持っている以上の権限で何かを実行しないでください。 Apacheへのアクセスがwww-dataに移行されたのには理由がありました。マシンでrootとして何かをする必要がある場合-そしてパスワードを変更したりアカウントを作成したりするのがこの「何か」-インターフェースを構築する必要があります。 php-scriptが何かをどこかに置き、ルートから実行されたスクリプトを介してこれをスキャンし、そこで処理します。あなたはf.e. www-dataがアクセスできるディレクトリに追加するユーザーを含むファイルを作成し、root-cronjobを介して5分(またはそれ以下)ごとにこれを実行し、ファイルをタイムスタンプ付きの完了フォルダーに移動して、ハプニング。

2
wolf

Webサーバーからより高い特権で何かを実行することは常に悪い考えであることに強く反対します。

Webアプリケーションのセキュリティ上の問題は、ユーザーが提供したデータを信頼することに起因するものであり、そのデータを使用している正確なプロセスに起因するものではありません。

つまり、データを検証およびサニタイズしない場合、名前付きパイプを介してルート所有プロセスにデータを渡すのは安全ではありませんそのデータを処理するラッパースクリプトを記述し、www-dataユーザーがSudo経由で実行できるようにします。

実際には、データのほとんどの処理/検証/サニタイズは、データがSudoスクリプトに渡される前に行う必要があります。Sudoスクリプトは、a)データの最終チェックを行い、b)実行する必要があります。より高い特権を必要とする操作のみ.

実際、後者の方が理解しやすいシンプルなソリューションであるため、後者の方が安全である可能性があると私は主張します。複雑なものを作るほど、間違いを犯す可能性が高くなります。

どちらの方法(名前付きパイプ、Sudoラッパーなど)を使用してもcrucialは、ユーザーが入力したデータを調べて、非常に適合することを確認することですそれを使って何かを行う前に、狭く定義された基準.

Web上のCGIセキュリティに関する記事やハウツーは数多くあります。ここには、stackexchangeサイトのいくつかの記事も含まれますが、一般的なテーマのいくつかは次のとおりです。

  • データをチェックまたは変更して安全にするまで、データは「汚染された」信頼できないものと見なしてください。
  • データを確認する-例許可または禁止されている文字の正規表現と一致するかどうかをテストします。最も安全なオプションは、何か奇妙なことがあった場合は中止することです。そうでない場合は、正規表現または何かで変換して、潜在的に安全でない要素を削除します。
  • alwaysデータを外部シェルスクリプトに渡す場合は、データを引用します。例えばシェルスクリプトでは、変数を二重引用符で囲む必要があります。
  • 同様に、データベースにデータを挿入するときは、エスケープや引用に依存するのではなく、プレースホルダー値をサポートするデータベースライブラリを使用する必要があります。 ここ は、その理由のユーモラスなイラストです。

続けることはできますが、ここで回答を要約するには多すぎます-CGIセキュリティは幅広いトピックです。 CGI Security または CGI入力の検証 でグーグル検索してみてください


「私はそれを使うのは私だけだから気にしない」という態度で、足を吹き飛ばすためにロードされたショットガンをあなたに与えているような気がしますが、足で自分を撃つことは貴重な学習体験です。ユーザーアカウントを作成する簡単なスクリプトを次に示します。ルート特権が必要です。

このスクリプトは、debianおよびdebian派生システムで使用可能なadduserに依存しています。システムにない場合は、代わりにuseraddを使用するように変更します。

#! /bin/bash 

# make the script abort on any error
set -e

U="$1"
P="$2"

[ -z "$U" ] && echo "Error: No username provided" >&2 && exit 1
[ -z "$P" ] && echo "Error: No password provided" >&2 && exit 1

# simple check - only allow lower-case letters and digits in usernames.
[ "$U" !~ '^[a-z0-9]*$' ] && echo "Error: Invalid Username" >&2 && exit 1

# create user if they don't already exist
if ! getent passwd "$U" > /dev/null ; then

   # create the user using adduser, must provide the gecos field 
   # and disable the password so adduser doesn't ask for them. 
   adduser --gecos "$U" --disabled-password "$U"

   # now change the password
   echo "$U:$P" | chpasswd
else
    echo "Error: Username already exists" >&2
    exit 1
fi

スクリプトをどこかに保存し、chmodで実行可能にします。

Www-dataがパスワードなしでrootとして実行できるようにするには、visudoを使用して/ etc/sudoersを編集し、以下を追加します。

Cmnd_Alias APACHEADDUSER = /path/to/makeaccount.sh

www-data ALL = NOPASSWD: APACHEADDUSER
5
cas