为简单起见,请考虑以下示例:我们有一个secret.php
运行后端代码的文件,该文件custom.php
在某处包含一个文件。显然,apache 用户必须能够读取这两个文件才能工作,但您能否阻止使用类似file_get_contents('secret.php')
获取源代码的方法?
在加载之前我们确实可以进行一些控制custom.php
,因此可以使用在 php 函数上带有白名单和/或黑名单的编码解决方案,但这增加了一层我不想使用的复杂性。
您能否以允许执行 php 文件但不允许读取它们的方式设置 apache / php / ubuntu?
答案1
尽管有很多方法可以通过操作系统限制文件访问,但这些方法都无法区分由同一可执行进程、同一用户、在同一上下文、在同一主机上运行的 PHP 脚本。
但是,您可以通过 open_basedir 在 PHP 内部强制实施约束 - 这可以在 Web 服务器配置中根据每个路径进行设置(或通过其他标准进行设置)。例如
<Directory /var/www/html>
php_admin_value open_basedir "/usr/share/php"
</Directory>
<Directory /var/www/html/privileged_scripts>
php_admin_value open_basedir "/usr/share/php:/usr/share/restricted"
</Directory>
然而,如果攻击者可以在您的网络服务器上运行他们的代码,这将不会提供太多的保护。
如上所述,这适用于直接映射到 URL 的 PHP 脚本 - 随后包含的脚本继承了该值。
答案2
显然,apache 用户必须能够读取这两个文件才能工作,但你可以避免使用类似 file_get_contents('secret.php') 之类的东西来获取源代码吗?
不可以。在类 UNIX 系统(如 Ubuntu Linux)上,文件访问权限是按进程分配的。因此,如果进程需要读取文件,则您必须授予该进程读取文件的能力 - 出于任何目的。
你能使用 seccomp 做更高级的事情,同时修改你的 PHP 源代码(甚至可能是 PHP 解释器)以禁用在某个时间点之后读取文件,但这将是合作的。
如果您需要在 secret.php 和 custom.php 之间设置安全边界,那么您可能至少应该将它们的进程分开,并让它们进行通信,例如通过域套接字、POSIX 共享内存、实际网络套接字或简单地通过管道。请注意,PHP 没有很好的表示“在与此进程相同的数据结构上工作的其他进程中运行的代码”,更不用说很好地表示 RPC 了,因此这一切都会产生大量的序列化/反序列化开销。
如果您不能信任您运行的代码(顺便说一句,这是 wordpress 实例被劫持的首要原因:不可信的代码在主题中运行,应该只修改 HTML 输出,但做险恶之事)。