我使用 suexec 来确保 PHP 脚本(和其他 CGI/FastCGI 应用程序)以与相关虚拟主机关联的帐户持有者身份运行。这可以确保每个用户的脚本不会被其他用户读取/写入。
然而,我发现这又带来了一个安全漏洞。以前,Web 服务器以非特权用户身份运行,对用户的文件具有只读访问权限(除非用户出于某种原因更改了文件权限)。现在,Web 服务器还可以写入用户的文件。
因此,虽然我已经阻止了不同的用户利用彼此的脚本,但我还是这样做了,如果某些应用程序存在远程代码注入漏洞,它现在不仅具有读取权限,而且还具有对该用户的所有脚本和网站的写入权限。
我该如何处理这个问题?
我有一个想法,就是为系统中的每个用户帐户创建第二个用户帐户,这样每个用户都有自己的用户帐户,并且他们的所有脚本都在另一个用户帐户下运行。但这似乎很麻烦。
答案1
在 Web 服务器的权限下运行 PHP 不一定更好的或者更差比使用 SuPHP 更好。这只是不同的。第一种模型将所有者与 Web 服务器分离,而第二种模型将所有者(及其 PHP 代码)与机器上的所有其他用户分离。
使用 suPHP 并不一定会提高您的整体安全性,它只是重定向了安全性。您不是试图防止入侵,而是将网站彼此隔离。理由是,特别是在共享托管环境中,以前的安全模型根本行不通:用户不断地通过设置所有内容的全局写入权限来破坏其安全性,以便 Web 应用程序可以正常工作,然后一个帐户的安全漏洞会迅速转移到服务器上的所有其他帐户。
因此,现在通常在大型共享托管环境中使用 suPHP 之类的工具来消除用户与其 PHP 应用程序之间的障碍,而是在用户与其邻居之间建立障碍。
因此,在这种情况下,您无需提供安全, 你提供分离。不幸的是,suPHP 要求文件拥有由您打算以何种用户身份运行,因此创建单独的 FTP 用户会……一团糟。您必须不断地chown
在 suPHP 用户和 FTP 用户之间来回传输文件。
相反,你需要选择一个角色:要么保护网站,要么保护服务器。如果你想保护网站,那么你需要将网络服务器与内容所有者分开。这是一个有点复杂的关系,很难正确维护,因此不建议在共享托管环境中使用。相反,如果你想保护服务器与其用户分离,然后使用 suPHP 将用户(及其代码)与服务器上的其他代码分开。在这种情况下,用户要对自己的安全负责。祝你好运,用户!从技术上讲,它是至少在理论上,有可能拥有一个安全的 PHP 应用程序。
答案2
首先,如果文件的所有者不需要具有写访问权限,请不要授予他们。您可以通过设置 UNIX 权限的第一个数字来实现这一点。这意味着只有 root 才能对其文件具有写访问权限。当他们需要升级文件但您说过他们不应该具有写访问权限时,这将非常烦人......
其次,他们以特定用户身份执行脚本。如果他们使用 open_basedir 锁定在文件中,那么他们可以写入文件就不是问题了。如果黑客入侵,只会破坏该用户的文件。即使没有 open_basedir,他们也只能写入文件,除非您拥有具有 777 权限的文件,这是另一个问题。
第三,许多网站至少需要对某些文件/文件夹具有写入权限。例如,Wordpress 需要在文件上传时进行写入。如果管理得当,网站的写入权限不一定是安全漏洞。
suexec 是一个很好的开始,并且 open_basedir 将确保具有写访问权限的用户留在定义的目录中。
答案3
suexec
我一直觉得这是一个临时解决方案,可以解决你处于一个固有的共享托管环境中这一事实——允许不受信任的请求以所有者用户的身份调用脚本是非常非常糟糕的(也是 WordPress 安装如何获得 root 权限的方式)——毕竟,如果你在专用主机上,你不会将所有文件都设置为模式 0777。仅仅删除写入权限不会有帮助,因为文件仍然拥有由该用户控制,因此最终可写。出于同样的原因,拥有两个不同的用户也无济于事。
在我看来,正确的解决方案是以非特权用户身份运行脚本,但是chroot
— — 也许 FastCGI 在这里是一个很好的解决方案...其中 fcgi 进程被 chrooted,但 Web 服务器知道在哪里找到它创建的套接字。
我意识到这不是一个“答案”,但我敢打赌有人之前已经提出过这个问题,并且可能已经实现了它 — — 甚至可能作为suexec
它自身的一个补丁(我设想ForceSUExecUID
并ForceSUExecGID
可以选择在每个虚拟主机上应用...)