我目前正在开发一个PHP框架。其他开发人员可以为框架创建模块。这些模块的源代码应该驻留在框架目录中。
由于项目是开源的,因此模块知道配置文件的位置,其中包含数据库密码。如何保护密码免受恶意模块的侵害?请检查模块可能只是require_once
配置文件并做有害的事情!
目前我将数据库密码存储在名为config的目录中,并通过.htaccess文件保护它:
<Directory config>
order allow,deny
deny from all
<Directory>
但这还不足以阻止脚本窃取密码,是吗?
我已经阅读了帖子How to secure database passwords in PHP?,但它没有帮助我找到答案。
答案 0 :(得分:3)
在PHP中,你不能。它不是沙盒语言;您运行的任何代码都会获得其运行的用户的所有权限。它可以读写文件,执行命令,建立网络连接等等。你必须完全信任你带入项目的任何代码,以便表现良好。
如果您需要安全边界,则必须通过权限分离自行实现它们。让每个模块作为具有极低权限的用户在其自己的进程中运行。然后,您需要某种进程间通信。这可能是使用操作系统级别的管道,或者使用单独的.php文件作为不同的用户运行,这些用户作为面向用户的脚本访问的Web服务运行。无论哪种方式,它都不能完全适合PHP应用程序的常用方式。
或者使用其他语言,例如Java,它可以提供受限制的代码,并对其允许的内容提供更强的保证(参见SecurityManager
等)。
答案 1 :(得分:2)
不幸的是,PHP不是一种非常安全的语言或运行时。但是,保护此类信息的最佳方法是在文档根目录之外提供包含用户名/密码的配置设置。此外,模块应该只使用您的API来获取数据库连接,而不是基于此文件创建自己的API。配置设置不应该是全局的。你应该以非常OOP的方式设计这样的东西,并提供必要的封装级别来阻止不必要的访问。
答案 2 :(得分:2)
我有一个可能适合您的想法,但这一切都取决于您的框架脚本具有哪些功能。为了让我的想法变得合情合理,你需要为你的框架文件创建一个沙箱。
一个想法: 你可以做什么(但可能是更多的资源密集型)是像文本文件一样读取每个模块。 然后,您需要识别在其脚本中读取文件的所有位置。你需要考虑fopen for file_get_contents。我可能做的一件事是告诉用户他们只能使用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方式。
答案 3 :(得分:1)
我不确定是否可能,但是你可以制作一个系统来检查模块中的文件是否有任何试图包含配置文件的php代码,然后在安装之前警告用户。
然而,它最终不应该是你的责任。
答案 4 :(得分:1)
一个非常好的问题,我知道没有好的答案,但是......
你见过runkit吗?它允许在PHP中进行沙盒化。
官方版本显然没有得到很好的维护,但GitHub上有一个很受欢迎的版本:zenovich/runkit on GitHub
虽然最好的解决方案可能是社区存储库,其中在给出可以使用的确定之前检查每个提交的安全性问题。
祝你的项目好运
答案 5 :(得分:1)
嗯,我觉得这里没问题。 如果它是一个模块,它可以根据定义做有害的事情,有或没有数据库访问。它可以删除文件,读取cookie等等。
因此,您必须信任这些模块(可能在审核之后)或拒绝使用模块。
答案 6 :(得分:0)
不要在开源项目中包含实际的配置文件。 我这样做的方法是创建模板配置文件config.ini.dist
当用户下载项目时,他们必须将其重命名为config.ini并输入自己的配置信息。
这样每个用户都有自己的数据库连接信息,如用户名和密码。此外,当您更新项目并且用户下载最新版本时,他们自己的配置文件将不会被您的程序覆盖。
这是在开源项目中存储配置的一种非常常见的方式 - 您分发模板配置文件并告诉用户必须重命名并输入自己的配置详细信息。
答案 7 :(得分:0)
我认为没有办法阻止模块从实际框架配置中捕获合理数据并将其发送给那些陌生人。另一方面,我认为应该保护用户免于发生这种情况。 毕竟,用户将决定安装任何模块,对吧?理论上应该是他必须验证模块意图。 例如,Drupal在这方面没有任何作用。 无论如何,还有一个最糟糕的问题:一旦安装了什么,会阻止一个令人讨厌的模块消灭整个数据库? 顺便说一下,恶意陌生人可以用你的数据库密码做什么?至少,您需要保护数据库的连接,以便只有可信主机才能连接到数据库服务器(例如,基于IP /主机的检查)。