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

发布于 2024-12-01 13:23:22 字数 491 浏览 1 评论 0原文

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

由于该项目是开源的,模块知道其中包含数据库密码的配置文件的位置。如何保护密码免受恶意模块的侵害?请检查模块是否可能仅 require_once 配置文件并执行有害操作!

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

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

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

我已阅读主题 如何保护 PHP 中的数据库密码?但这并没有帮助我找到答案。

I'm currently developing a PHP framework. Other developers may create modules for the framework. Source code of these modules should reside in the framework directory.

Since the project is open-source, modules know location of the config file which has database password in it. How to protect passwords from malicious modules? Please check that modules may just require_once the config file and do harmful things!

Currently I'm storing Database passwords in a directory named config, and protecting it by a .htaccess file:

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

But that is not sufficient to prevent scripts steal the password, is it?

I've read the thread How to secure database passwords in PHP? but it did not help me finding the answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

沒落の蓅哖 2024-12-08 13:23:22

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

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

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

In PHP, you can't. It's not a sandboxed language; any code you run gets all the permissions of the user it's running under. It can read and write files, execute commands, make network connections, and so on, You must absolutely trust any code you're bringing in to your project to behave well.

If you need security boundaries, you would have to implement them yourself through privilege separation. Have each module run in its own process, as a user with very low privileges. Then you need some sort of inter-process communication. That could be using OS-level pipes, or by having separate .php files run as different users running as web services accessed by the user-facing scripts. Either way, it doesn't fit neatly into the usual way PHP applications work.

Or use another language such as Java, which can offer restricted code with stronger guarantees about what it is allowed to do (see SecurityManager et al).

单身情人 2024-12-08 13:23:22

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

Unfortunately, PHP is not a very secure language or runtime. However, the best way to secure this sort of information is to provide a configuration setting that has your username/password in it, outside of your document root. In addition, the modules should just use your API to get a database connection, not create one of their own based on this file. The config setting should not be global. You should design something like this in a very OOP style and provide the necessary level of encapsulation to block unwarranted access.

世界如花海般美丽 2024-12-08 13:23:22

我有一个可能适合您的想法,但这实际上取决于您的框架脚本具有什么功能。为了使我的想法在安全方面合理,您需要为框架文件创建一个沙箱。

一个想法:
您可以做的(但可能需要更多资源)是像读取文本文件一样读取每个模块。
然后,您需要识别在其脚本中读取文件的所有位置。您需要考虑诸如 fopen 等 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 方法。

I've got an idea that may work for you, but it all really depends on what abilities your framework scripts have. For my idea to be plausible security wise you need to essentially create a sandbox for your framework files.

One idea:
What you could do (but probably more resource intensive) is read each module like you would a text file.
Then you need to identify everywhere that reads a file within their script. You've got things like fopen for file_get_contents to consider. One thing I'd probably do is tell the users they may only read and write files using file_get_contents and file_put_contents, then use a tool to strip out any other file write/read functions from their script (like fopen).
Then write your own function to replace file_get_contents and file_put_contents, make their script use your function rather than PHP's file_get_contents and file_put_contents. In your file_get_contents function you're essentially going to be checking permissions; are they accessing your config file, yes or no, then return a string saying "access denied" if they are or you use the real file_get_contents to read and return the file if not.
As for your file_put_contents, you just need to make sure they're not writing files to your server (they shouldn't be allowed, imagine what they could do!), alternatively, you could probably use a CHMOD to stop that happening.
Once you've essentially rewritten the module in memory, to be secure, you then use the "exec" function to execute it.

This would take a considerable amount of work - but it's the only pure PHP way I can think of.

原来是傀儡 2024-12-08 13:23:22

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

然而,最终这确实不应该是你的责任。

I am not sure if it is possible, however you could maybe make a system which checks the files in the module for any php code which tries to include the config file, and then warn the user about it before installing.

However it really shouldn't be your responsibility in the end.

荒岛晴空 2024-12-08 13:23:22

这是一个非常好的问题,据我所知没有好的答案,但是......

你见过 runkit?它允许 PHP 中的沙箱。

官方版本显然已经维护得不好了,但是 GitHub 上有一个非常受欢迎的版本: zenovich GitHub 上的 /runkit

尽管最好的解决方案可能是社区存储库,其中每个提交都会在获得使用许可之前检查安全问题。

祝你的项目好运

A very good question with no good answer that I know of, however...

Have you seen runkit? It allows for sandboxing in PHP.

The official version apparently isn't well maintained any more, however there is a version on GitHub that is quite popular: zenovich/runkit on GitHub

Although the best solution is perhaps a community repository where every submission is checked for security issues before being given the OK to use.

Good Luck with your project

破晓 2024-12-08 13:23:22

嗯,我认为这里没有问题。
如果它是一个模块,那么根据定义,无论有或没有数据库访问,它都可以做有害的事情。它可以删除文件、读取cookie等。

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

Well, I see no problem here.
If it's a module, it can do harmful things by definition, with or without database access. It can delete files, read cookies, etc etc.

So, you have to either trust to these modules (may be after reviewing them) or refuse to use modules at all.

歌枕肩 2024-12-08 13:23:22

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

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

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

这是在开源项目中存储配置的一种非常常见的方法 - 您分发模板配置文件并告诉用户他们必须重命名它并输入自己的配置详细信息。

Don't include your actual config file in your open source project.
The way I do it is a create just the template config file config.ini.dist

When a user downloads your project they have to rename it to config.ini and enter their own configuration information.

This way every user will have their own database connection info like username and password. Also when you update your project and users download your newest version, their own config files will not be overwritten by the one from your program.

This a a very common way to store configuration in open source projects - you distribute a template config file and tell users that they have to rename it and enter their own configuration details.

情深已缘浅 2024-12-08 13:23:22

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

I don't think there is a way to prevent a module to capture sensible data from the actual framework configuration and send it to some stranger out there. On the other end, I don't think that should be your responsability to protect the user from that to happen.
After all, it's the user that will decide to install any module, right? In theory it should be him that would have to verify the module intents.
Drupal, for example, does nothing in this direction.
There is a worst problem, anyway: what'd prevent a nasty module to wipe out your entire database, once it is installed?
And, by the way, what could the malicious stranger do with your database password? At the very least you anyway need to secure the connection of the database, so that only trusted hosts can connect to the database server (IP/host based check, for example).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文