许多PHP程序要求用户以明文形式(以字符串或常量形式)将mysql密码存储在应用程序根目录的配置文件中,这一直困扰着我。
这些年来有没有更好的方法呢?
到目前为止,我已经提出了两个最小的安全性提升:
使用.htaccess中的规则通过网络使文件无法读取 (如果php失败或者有安全漏洞来读取php源代码)
在建立数据库连接后销毁内存中的密码(未设置) (防止来自安全漏洞,注入等的字符串转储)
但当然这些都没有解决原来的问题。
感谢您的任何其他想法!
答案 0 :(得分:25)
就个人而言,我将敏感信息(如数据库连接详细信息)存储在我的Web文件夹根目录之外的 config.ini 文件中。然后在我的 index.php 中,我可以这样做:
$config = parse_ini_file('../config.ini');
这意味着如果您的服务器意外开始以纯文本形式输出PHP脚本(之前发生过,臭名昭着的Facebook),则变量不可见;并且只有PHP脚本才能访问变量。
它也不依赖于 .htaccess ,如果您的 .htaccess 文件被移动或销毁,则没有意外情况。
警告,2017年2月14日补充:我现在将这样的配置参数存储为环境变量。我暂时没有使用 .ini 文件方法。
答案 1 :(得分:12)
将配置文件保留在文档根目录之外是提高配置文件安全性的常用方法。
答案 2 :(得分:12)
由于您的代码需要密码,因此没有完美的安全性。但是你可以让它很难恢复。
我在我的网络配置中添加了一些哈希,作为环境变量,比如MYSQL_PASS_HASH
然后我会做md5(getenv('MYSQL_PASS_HASH').'gibberish$qwefsdf')
这样的密码。当然,如果你是偏执狂,你应该unsetenv
。
您的密码不会存储在某个地方,只有当您的网络配置和包含数据库时,才能恢复密码。
这发生在webroot之外的文件中(不要完全信任.htaccess
)。
答案 3 :(得分:2)
当然,您不应该将密码存储在文档根目录中的纯文本文件中。您采取哪些进一步措施来保护它将取决于您配置Web服务器所需的访问级别。
您可以在php.ini中定义密码(或通过Apache配置或.htaccess中的ini设置)。或者在启动网络服务器时将其设置在环境中。
加密密码没有意义 - 这意味着您需要存储解密密钥 - 除非您使用用户提供的密码和Quorum身份验证来解密密码(但这可以防止未经过身份验证的会话访问数据库,以及当你需要将新用户添加到法定人数时会变得混乱。)
如果它是一个廉价的托管包,你在文件根目录外没有可访问的存储,那么将密码存储在一个php包含文件中应该防止它被暴露(文件将被下载的php intead解析)。或者,简单地在开头用'.ht'命名文件可能会阻止远程访问。
请注意,您的第二个选项有点多余 - 如果有人可以对您的代码造成太大的损害,那么他们就不需要从正在运行的代码中提取密码。
真的没有解决问题的办法。
下进行。
答案 4 :(得分:2)
除了正确存储这些敏感数据外,还应该create a separate MySQL user只需要访问它所需的数据库/表/视图所需的privileges and restrict the access。由于数据库服务器通常与Web服务器在同一台机器上运行,因此也限制对本地访问的访问。因此,如果只需要从单个数据库/表中读取数据,请不要使用具有root权限的用户。
答案 5 :(得分:1)
如果您愿意权衡文件安全性的可用性,您可以从配置文件中取出密码,并要求管理员在启动时输入密码并将其存储在全局变量中。
你仍然必须确保你能够安全地接受可以转储该变量的注入攻击,当然你在(重新)启动过程中有一个手动步骤。
答案 6 :(得分:0)
它不必在webroot中。您可以将文件移到webroot之外并以此方式调用它。这只是意味着无法直接从Web调用该文件。
如果您的代码中存在安全漏洞,例如包含没有从GET数据过滤的内容,则该文件仍然存在风险。真正的关键是确保您的应用程序也是安全的。
答案 7 :(得分:0)
您可以在.htaccess文件中设置环境变量,例如:
SetEnv DBuser sesame
SetEnv DBpass street
然后在代码中读取,使用和删除条目。