如何在 PHP 中保护数据库密码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/97984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to secure database passwords in PHP?
提问by user18359
When a PHP application makes a database connection it of course generally needs to pass a login and password. If I'm using a single, minimum-permission login for my application, then the PHP needs to know that login and password somewhere. What is the best way to secure that password? It seems like just writing it in the PHP code isn't a good idea.
当 PHP 应用程序建立数据库连接时,它当然通常需要传递登录名和密码。如果我为我的应用程序使用单一的、最低权限的登录名,那么 PHP 需要在某处知道该登录名和密码。保护该密码的最佳方法是什么?似乎只是在 PHP 代码中编写它并不是一个好主意。
采纳答案by user11318
Several people misread this as a question about how to storepasswords in a database. That is wrong. It is about how to store the password that lets you get tothe database.
一些人将此误读为关于如何在数据库中存储密码的问题。那是错的。它是关于如何存储让您访问数据库的密码。
The usual solution is to move the password out of source-code into a configuration file. Then leave administration and securing that configuration file up to your system administrators. That way developers do not need to know anything about the production passwords, and there is no record of the password in your source-control.
通常的解决方案是将密码从源代码中移到配置文件中。然后让系统管理员负责管理和保护该配置文件。这样开发人员不需要知道任何关于生产密码的信息,并且在你的源代码控制中没有密码记录。
回答by kellen
If you're hosting on someone else's server and don't have access outside your webroot, you can always put your password and/or database connection in a file and then lock the file using a .htaccess:
如果您托管在其他人的服务器上并且在您的 webroot 之外没有访问权限,您始终可以将您的密码和/或数据库连接放在一个文件中,然后使用 .htaccess 锁定该文件:
<files mypasswdfile>
order allow,deny
deny from all
</files>
回答by Lars Nystr?m
The most secure way is to not have the information specified in your PHP code at all.
最安全的方法是根本没有在 PHP 代码中指定的信息。
If you're using Apache that means to set the connection details in your httpd.conf or virtual hosts file file. If you do that you can call mysql_connect() with no parameters, which means PHP will never ever output your information.
如果您使用 Apache,则意味着在 httpd.conf 或虚拟主机文件文件中设置连接详细信息。如果这样做,您可以不带参数调用 mysql_connect(),这意味着 PHP 永远不会输出您的信息。
This is how you specify these values in those files:
这是在这些文件中指定这些值的方式:
php_value mysql.default.user myusername
php_value mysql.default.password mypassword
php_value mysql.default.host server
Then you open your mysql connection like this:
然后你像这样打开你的 mysql 连接:
<?php
$db = mysqli_connect();
Or like this:
或者像这样:
<?php
$db = mysqli_connect(ini_get("mysql.default.user"),
ini_get("mysql.default.password"),
ini_get("mysql.default.host"));
回答by da5id
Store them in a file outside web root.
将它们存储在 Web 根目录之外的文件中。
回答by pdavis
For extremely secure systems we encrypt the database password in a configuration file (which itself is secured by the system administrator). On application/server startup the application then prompts the system administrator for the decryption key. The database password is then read from the config file, decrypted, and stored in memory for future use. Still not 100% secure since it is stored in memory decrypted, but you have to call it 'secure enough' at some point!
对于极其安全的系统,我们在配置文件中加密数据库密码(它本身由系统管理员保护)。在应用程序/服务器启动时,应用程序会提示系统管理员输入解密密钥。然后从配置文件中读取数据库密码,解密并存储在内存中以备将来使用。仍然不是 100% 安全,因为它存储在已解密的内存中,但您必须在某个时候称其为“足够安全”!
回答by Neil McGuigan
This solution is general, in that it is useful for both open and closed source applications.
此解决方案是通用的,因为它对开源和闭源应用程序都很有用。
- Create an OS user for your application. See http://en.wikipedia.org/wiki/Principle_of_least_privilege
- Create a (non-session) OS environment variable for that user, with the password
- Run the application as that user
- 为您的应用程序创建操作系统用户。见http://en.wikipedia.org/wiki/Principle_of_least_privilege
- 使用密码为该用户创建一个(非会话)操作系统环境变量
- 以该用户身份运行应用程序
Advantages:
好处:
- You won't check your passwords into source control by accident, because you can't
- You won't accidentally screw up file permissions. Well, you might, but it won't affect this.
- Can only be read by root or that user. Root can read all your files and encryption keys anyways.
- If you use encryption, how are you storing the key securely?
- Works x-platform
- Be sure to not pass the envvar to untrusted child processes
- 您不会意外地将密码检查到源代码管理中,因为您不能
- 您不会意外搞砸文件权限。嗯,你可能会,但它不会影响这个。
- 只能由 root 或该用户读取。无论如何,root 都可以读取您的所有文件和加密密钥。
- 如果您使用加密,您如何安全地存储密钥?
- 适用于 x 平台
- 确保不要将 envvar 传递给不受信任的子进程
This method is suggested by Heroku, who are very successful.
这个方法是 Heroku 推荐的,非常成功。
回答by Bob Fanger
if it is possible to create the database connection in the same file where the credentials are stored. Inline the credentials in the connect statement.
如果可以在存储凭据的同一文件中创建数据库连接。在连接语句中内联凭据。
mysql_connect("localhost", "me", "mypass");
Otherwise it is best to unset the credentials after the connect statement, because credentials that are not in memory, can't be read from memory;)
否则最好在 connect 语句之后取消设置凭据,因为不在内存中的凭据无法从内存中读取;)
include("/outside-webroot/db_settings.php");
mysql_connect("localhost", $db_user, $db_pass);
unset ($db_user, $db_pass);
回答by Courtney Miles
Previously we stored DB user/pass in a configuration file, but have since hit paranoid mode -- adopting a policy of Defence in Depth.
以前我们将数据库用户/密码存储在配置文件中,但此后已进入偏执模式——采用深度防御策略。
If your application is compromised, the user will have read access to your configuration file and so there is potential for a cracker to read this information. Configuration files can also get caught up in version control, or copied around servers.
如果您的应用程序受到威胁,用户将拥有对您的配置文件的读取权限,因此破解者有可能读取此信息。配置文件也可能陷入版本控制,或在服务器上复制。
We have switched to storing user/pass in environment variables set in the Apache VirtualHost. This configuration is only readable by root -- hopefully your Apache user is not running as root.
我们已经切换到在 Apache VirtualHost 中设置的环境变量中存储用户/密码。这个配置只能被 root 读取——希望你的 Apache 用户没有以 root 身份运行。
The con with this is that now the password is in a Global PHP variable.
与此相反的是,现在密码在全局 PHP 变量中。
To mitigate this risk we have the following precautions:
为了降低这种风险,我们采取了以下预防措施:
- The password is encrypted.We extend the PDO class to include logic for decrypting the password. If someone reads the code where we establish a connection, it won't be obvious that the connection is being established with an encrypted password and not the password itself.
- The encrypted password is moved from the global variables into a private variableThe application does this immediately to reduce the window that the value is available in the global space.
phpinfo()is disabled.PHPInfo is an easy target to get an overview of everything, including environment variables.
- 密码是加密的。我们扩展 PDO 类以包含用于解密密码的逻辑。如果有人阅读了我们建立连接的代码,那么很明显连接是使用加密密码而不是密码本身建立的。
- 加密的密码从全局变量移动到私有变量应用程序立即执行此操作以减少该值在全局空间中可用的窗口。
phpinfo()被禁用。PHPInfo 是一个简单的目标,可以了解所有内容,包括环境变量。
回答by Vagnerr
Your choices are kind of limited as as you say you need the password to access the database. One general approach is to store the username and password in a seperate configuration file rather than the main script. Then be sure to store that outside the main web tree. That was if there is a web configuration problem that leaves your php files being simply displayed as text rather than being executed you haven't exposed the password.
您的选择是有限的,因为您说访问数据库需要密码。一种通用方法是将用户名和密码存储在单独的配置文件而不是主脚本中。然后确保将其存储在主网络树之外。那是如果存在 Web 配置问题,使您的 php 文件仅显示为文本而不是被执行,则您没有公开密码。
Other than that you are on the right lines with minimal access for the account being used. Add to that
除此之外,您处于正确的行上,对正在使用的帐户的访问权限最小。添加到那个
- Don't use the combination of username/password for anything else
- Configure the database server to only accept connections from the web host for that user (localhost is even better if the DB is on the same machine) That way even if the credentials are exposed they are no use to anyone unless they have other access to the machine.
- Obfuscate the password (even ROT13 will do) it won't put up much defense if some does get access to the file, but at least it will prevent casual viewing of it.
- 不要将用户名/密码组合用于其他任何用途
- 将数据库服务器配置为仅接受来自该用户的 Web 主机的连接(如果 DB 位于同一台机器上,则 localhost 甚至更好)这样即使公开了凭据,它们也不会对任何人有用,除非他们有其他访问权限机器。
- 混淆密码(即使 ROT13 也可以),如果某些人确实可以访问该文件,它不会提供太多防御,但至少可以防止随意查看它。
Peter
彼得
回答by Jim
If you are using PostgreSQL, then it looks in ~/.pgpassfor passwords automatically. See the manualfor more information.
如果您使用的是 PostgreSQL,那么它会~/.pgpass自动查找密码。有关更多信息,请参阅手册。

