PHP 和 MySQL-如何在源代码中避免密码?

我有一个小的 PHP 应用程序存储在 MySQL数据库中的数据。目前,用户名/密码在 PHP 代码中是硬编码的。例如,我不喜欢这种情况,因为代码也可以在存储库中获得。

我的最佳想法是将数据从代码移动到配置文件(从存储库中排除) ,然后以某种方式对其进行编码,因此不能直接读取(模糊处理)。有没有更好更容易使用的方法来解决这个问题?

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db('mydb');

范围: 我想建立一个健壮的,但也易于使用的解决方案。我需要合理的安全措施,但我不是在处理高度机密的数据。

备注: 不再推荐使用 mysql_connect函数,请参阅 PHP 中的 Stack Overflow 问题 为什么我不应该使用 mysql _函数? * .我本来可以更改代码示例,但是由于一些注释提到了这一点,所以我没有更改。然而,这个问题的本质仍然有效。

17395 次浏览

我要做的是只在存储库中存储示例配置文件,比如 config.php.dist,而不将实际的 config.php 置于版本控制之下。

如您所说,最简单的方法是使用配置文件。

许多框架使用这种方法(赞德CakePHPKohana等等) ,这是最常用的方法(即使在非 PHP 环境中,如 ASP.NET 及其 web.config文件中)。这还允许您通过仅仅复制站点的文件来将配置值从一个环境复制到另一个环境,这比依赖服务器设置环境变量(这些变量很快就会丢失和遗忘)有好处。

你不需要担心密码的混淆,因为它不是一个世界可访问的文件,它当然不应该是网络可访问的。我的意思是,你要么 a)告诉你的网络服务器不要提供你的配置文件(IIS已经用 web.config文件做到了这一点,并提供一个 HTTP 404.8状态,而不是内容)或者 b)把它移出你的网络服务目录。如果有人可以看到您的配置文件,这比在源代码中使用它更糟糕。

有一个配置文件的基本版本(空/默认) ,并在每个环境中将其分离出来,这也是一个好主意,这样您就可以为生产、开发和测试平台使用不同的配置文件。

环境变量是区分这些环境最常用的方法,比如下面的代码:

// Check if it's been set by the web server
if (!empty($_ENV['ENVIRONMENT'])) {
// Copy from web server to PHP constant
define('ENVIRONMENT', $_ENV['ENVIRONMENT']);
}


if (!defined('ENVIRONMENT')) {
// Default to development
define('ENVIRONMENT', 'development');
}


// Load in default configuration values
require_once 'config.default.php';


// Load in the overridden configuration file for this environment
require_once 'config.' . ENVIRONMENT . '.php';

另一种非常常见的方法是使用 XML 配置文件,并且只读入您需要的适当值(在内存中存储配置文件的缓存副本)。这很容易被限制为只加载某些值,而不是允许任意包含 PHP 文件,在我看来,这是一个更好的解决方案,但是上面的内容应该会让您朝着正确的方向开始。

您可能希望 VCS忽略该文件。另一方面,您可能希望文件的框架或具有合理默认值的框架(当然,后者不适用于登录数据)受版本控制。处理这个问题的一种常见方法是使用签入模板配置文件,安装过程将该文件复制到实际配置文件的位置,并在该位置进行自定义。这可以是手动的,也可以是自动的过程。

(虽然与主要问题无关,但是为您的环境引入一个常量可以让您做一些其他很酷的事情,比如推迟使用假的邮件实现而不是实时的 SMTP实现,当然这也可以通过配置文件来实现)

一个相当不错的解决方案,如果您在 Apache 上,它可以将信息存储在虚拟主机配置中

SetEnv  MYSQL_USER     "xx"
SetEnv  MYSQL_PASSWORD "y2wrg435yw8"

使用 $_ENV[]可以很容易地获取数据,以便在代码中使用。

最好将密码从代码移动到配置文件,这样密码就不会在存储库中。在配置文件中对其进行加密的想法是值得怀疑的,因为拥有配置文件 + PHP 解密代码的人总是可以运行代码并获得明文密码。也许将密码以纯文本形式保存在配置文件中并考虑如何保护配置文件不受未经授权的访问会更好。

您总是可以使用函数 Rel = “ nofollow”> parse _ ini _ file 创建一个配置 ini 文件。

问得好。您可以将最敏感的部分(例如密钥/密码)作为环境变量移出,但是这只会将问题推迟到您的服务器配置(可能也在存储库中)。

您也可以尝试避免像数据库这样的东西的密码,使其密码更少,并将其保护在防火墙之后。这些都不是完美的解决方案,但它们是我所知道的方法。

我不觉得这有什么问题。如果您共享一个存储库,您可能不希望硬编码密码和配置。你应该提供默认值:

host: localhost
user: root
pass: root
name: db

如果你真的想要,你可以使用和解析一个 .ini文件,但它很可能是非常缓慢的比一个数组正在设置的源代码,并没有真正的意义给我。

记住: 你唯一可以信任的就是你的源代码,如果他们能得到它,无论如何你都完蛋了。

正如其他人所提到的,将它放在源代码控制之外的一个单独的配置文件中(显然这将在源代码控制之下的代码中提到)。

将文件命名为 Config.php而不是 Config.ini也是一个好主意,以防意外暴露目录,这意味着文件不会被下载,而是什么也不会返回。

如果您认为 12因素方法很有价值,他们建议在环境中存储配置。

这样做还有一个额外的好处,就是允许您在测试或非生产环境中编写 完全一样的密码。如果您希望(或需要)更改数据库或其他任何内容,则不需要修改代码-只需更改环境变量即可。