防止脚本在开源PHP项目中窃取密码



我目前正在开发一个PHP框架。其他开发人员可以为该框架创建模块。这些模块的源代码应该位于框架目录中。

由于项目是开源的,模块知道配置文件的位置,其中包含数据库密码。如何保护密码免受恶意模块的攻击?请检查模块可能只是require_once配置文件和做有害的事情!

目前我将数据库密码存储在一个名为config的目录中,并通过。htaccess文件保护它:

<Directory config>
order allow,deny
deny from all
<Directory>

但这并不足以防止脚本窃取密码,是吗?

我已经读了线程如何在PHP中保护数据库密码?但这并没有帮助我找到答案。

在PHP中,你不能。它不是一种沙盒语言;您运行的任何代码都将获得其所在用户的所有权限。它可以读写文件,执行命令,建立网络连接,等等。你必须绝对相信你带到项目中的任何代码都表现良好。

如果需要安全边界,则必须通过特权分离自己实现它们。让每个模块在自己的进程中运行,使用权限非常低的用户。然后需要某种进程间通信。这可以使用操作系统级别的管道,或者让不同的.php文件作为不同的用户运行,作为面向用户的脚本访问的web服务运行。无论哪种方式,它都不适合PHP应用程序的正常工作方式。

或者使用另一种语言,例如Java,它可以提供受限制的代码,并对允许执行的操作提供更强的保证(参见SecurityManager等)。

不幸的是,PHP不是一种非常安全的语言或运行时。但是,保护这类信息的最佳方法是在文档根目录之外提供一个包含用户名/密码的配置设置。此外,模块应该只使用您的API来获取数据库连接,而不是基于该文件创建自己的数据库连接。配置设置不应该是全局的。您应该以非常面向对象的风格设计类似的东西,并提供必要的封装级别以阻止未经授权的访问。

我有一个想法,可能对你有用,但这一切都取决于你的框架脚本有什么能力。为了使我的想法在安全性方面可行,您需要为您的框架文件创建一个沙箱。

一个想法:您可以做的(但可能更耗费资源)是像读取文本文件一样读取每个模块。然后,您需要识别脚本中读取文件的所有位置。您需要考虑file_get_contents的fopen等操作。我可能会做的一件事是告诉用户他们只能使用file_get_contents和file_put_contents读写文件,然后使用工具从脚本中删除任何其他文件写/读函数(如fopen)。然后编写自己的函数来替换file_get_contents和file_put_contents,使它们的脚本使用您的函数而不是PHP的file_get_contents和file_put_contents。file_get_contents函数会检查权限;他们是否访问你的配置文件,是或否,然后返回一个字符串说"拒绝访问",如果他们是,或者你使用真正的file_get_contents来读取和返回文件,如果没有。至于file_put_contents,您只需要确保它们没有向服务器写入文件(它们不应该被允许,想象一下它们能做什么!),或者,您可能可以使用CHMOD来阻止这种情况的发生。一旦您在内存中重写了模块,为了安全起见,您就可以使用"exec"函数来执行它。

这将需要相当多的工作-但这是我能想到的唯一纯PHP方法。

我不确定是否有可能,但是你可以制作一个系统,检查模块中任何php代码的文件,这些代码试图包含配置文件,然后在安装之前警告用户。

然而,它最终真的不应该是你的责任。

一个很好的问题,但我知道没有好的答案,然而…

你看过runkit吗?它允许在PHP中使用沙箱。

官方版本显然没有得到很好的维护,但是GitHub上有一个非常受欢迎的版本:zenovich/runkit在GitHub

虽然最好的解决方案可能是一个社区存储库,每个提交在被允许使用之前都要检查安全问题。

祝你项目顺利

嗯,我看没有问题。如果它是一个模块,根据定义,无论是否有数据库访问,它都可能做有害的事情。它可以删除文件,读取cookie等。

因此,您必须要么信任这些模块(可能是在检查它们之后),要么根本拒绝使用模块。

不要在你的开源项目中包含你实际的配置文件。我的方法是创建模板配置文件config.ini.dist

当用户下载你的项目时,他们必须将其重命名为config.ini并输入他们自己的配置信息。

这样每个用户都有自己的数据库连接信息,如用户名和密码。另外,当你更新你的项目和用户下载你的最新版本时,他们自己的配置文件将不会被你的程序中的配置文件覆盖。

这是在开源项目中存储配置的一种非常常见的方式——你分发一个模板配置文件,告诉用户他们必须重命名它,并输入他们自己的配置细节。

我不认为有一种方法可以阻止模块从实际框架配置中捕获合理的数据并将其发送给一些陌生人。另一方面,我认为你不应该有责任保护用户免受这种情况的发生。毕竟,是用户决定安装任何模块,对吗?理论上,应该由他来验证模块的意图。例如,Drupal在这个方向上没有做任何事情。无论如何,还有一个最糟糕的问题:一旦安装了一个讨厌的模块,如何防止它清除整个数据库?顺便说一下,恶意的陌生人会用你的数据库密码做什么呢?无论如何,您至少需要保护数据库的连接,以便只有受信任的主机才能连接到数据库服务器(例如,基于IP/主机的检查)。

最新更新