以root用户身份从php执行shell脚本?

qwe*_*rty 5 shell scripting sudo php apache-httpd

需要从 PHP 执行以下行:

$res = shell_exec('sudo sh /home/nicklas/cronjobs/make_account.sh 用户名密码');

问题是执行时什么也没有发生。如果我尝试 echo $res ,它会出现空白。我也试过使用 system() ,结果相同。我猜它不起作用,因为我需要以 root 访问权限运行脚本,而 www-data 用户默认情况下没有。我将以下行添加到 /etc/sudoers 以希望获得访问权限:

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

但没有成功。我试过在两者之间重新启动 apache,没有任何改变。

我错过了什么吗?

cas*_*cas 5

我强烈不同意从 Web 服务器运行具有更高权限的东西总是一个坏主意。

Web 应用程序的安全问题来自信任用户提供的数据,而不是来自使用该数据的确切过程。

换句话说,如果你不验证和净化你的数据,这是没有安全通过命名管道将它传递给根拥有的进程比它写一个包装脚本来处理数据,并允许www数据用户通过 sudo 运行它。

实际上,大部分数据的处理/验证/清理应该在数据传递给 sudo 脚本之前完成,这应该 a) 对数据进行最终检查,以及 b)执行需要更高权限的操作。

事实上,我认为后者可能更安全,因为它是一个更简单的解决方案,更容易理解......你做的事情越复杂,你犯错误的可能性就越大。

无论您使用哪种方法(命名管道、sudo 包装器或其他方法),关键在于您检查用户提供的数据并确保它符合非常狭窄的标准,然后再对其进行任何操作

网络上有许多关于 CGI 安全性的文章和方法,包括 stackexchange 站点上的几篇,但一些常见的主题是:

  • 在您检查和/或修改数据以使其安全之前,将数据视为“受污染”且不可信。
  • 检查数据 - 例如测试它是否与允许或禁止字符的正则表达式匹配。最安全的选择是在有任何奇怪的情况下中止,否则使用正则表达式或其他内容对其进行转换以删除潜在的不安全元素。
  • 如果您将数据传递给外部 shell 脚本,请始终引用数据。例如,shell 脚本应该在变量周围使用双引号。
  • 同样,在将数据插入数据库时​​,您应该使用支持占位符值的数据库库,而不是依赖于转义或引用。这里有一个幽默的说明为什么。

我可以继续,但是这里的答案太多了 - CGI 安全是一个广泛的主题。尝试谷歌搜索CGI 安全验证 CGI 输入


以你的“我不在乎,因为只有我在使用它”对安全的态度,我有点觉得我在给你一把上膛的霰弹枪来炸掉你的脚,但是用脚射击自己是一种宝贵的学习经验. 这是创建用户帐户的简单脚本。它需要根权限。

该脚本依赖于 adduser,它可用于 debian 和 debian 派生系统以及其他系统。如果它不在您的系统上,请修改为使用 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
Run Code Online (Sandbox Code Playgroud)

将脚本保存在某处,并使用 chmod 使其可执行。

要允许 www-data 在没有密码的情况下以 root 身份运行它,请编辑 /etc/sudoersvisudo并添加以下内容:

Cmnd_Alias APACHEADDUSER = /path/to/makeaccount.sh

www-data ALL = NOPASSWD: APACHEADDUSER
Run Code Online (Sandbox Code Playgroud)


num*_*run 2

出于安全原因,您永远不应该尝试使用具有比其自然拥有的更多权限的用户 www-data 来执行某些操作。前段时间 Apache 访问被转移到 www-data 是有原因的。如果您需要以 root 身份在计算机上执行某些操作 - 并且更改密码或创建帐户就是这个“操作” - 您应该构建一个界面。让 php 脚本将某些内容放在某处,并通过从 root 执行的脚本扫描它并在那里处理它。您可以创建一个包含要添加到 www-data 可以访问的目录中的用户的文件,然后每 5 分钟(或更短时间)通过 root-cronjob 执行此操作,并将文件移动到带有时间戳的完成文件夹中以进行控制关于正在发生的事情。