首页 文章

如何在PHP中保护数据库密码?

提问于
浏览
361

当PHP应用程序 Build 数据库连接时,它当然通常需要传递登录名和密码 . 如果我正在为我的应用程序使用单个最小权限登录,那么PHP需要知道某处的登录名和密码 . 保护密码的最佳方法是什么?看起来只是在PHP代码中编写它并不是一个好主意 .

17 回答

  • 94

    只需将它放入某个配置文件就可以了 . 请确保你:

    • 禁止从网络外的任何服务器访问数据库,

    • 注意不要意外地向用户显示密码(在错误消息中,或通过PHP文件意外地作为HTML等提供 . )

  • 3

    有些人误以为这是关于如何在数据库中使用 store 密码的问题 . 那是错的 . 它是关于如何存储密码,让您获得 to 数据库 .

    通常的解决方案是将密码从源代码中移出到配置文件中 . 然后将管理和保护配置文件保留给系统管理员 . 这样开发人员就不需要了解 生产环境 密码的任何信息,并且源代码控制中没有密码记录 .

  • 4

    如果您在其他人的服务器上托管并且无法访问您的webroot,您可以始终将您的密码和/或数据库连接放在一个文件中,然后使用.htaccess锁定该文件:

    <files mypasswdfile>
    order allow,deny
    deny from all
    </files>
    
  • 36

    将它们存储在Web根目录之外的文件中 .

  • 5

    最好的方法是不要存储密码!
    例如,如果你是're on a Windows system, and connecting to SQL Server, you can use Integrated Authentication to connect to the database without a password, using the current process'的身份 .

    如果确实需要连接密码,首先使用强加密(例如使用AES-256,然后保护加密密钥,或使用非对称加密并让操作系统保护证书),然后将其存储在密码中使用 strong ACLs 配置文件(在Web目录之外) .

  • 36

    最安全的方法是根本不具备PHP代码中指定的信息 .

    如果您正在使用Apache,则意味着在httpd.conf或虚拟主机文件文件中设置连接详细信息 . 如果你这样做,你可以调用不带参数的mysql_connect(),这意味着PHP永远不会输出你的信息 .

    这是您在这些文件中指定这些值的方法:

    php_value mysql.default.user      myusername
    php_value mysql.default.password  mypassword
    php_value mysql.default.host      server
    

    然后你打开你的mysql连接,如下所示:

    <?php
    $db = mysqli_connect();
    

    或者像这样:

    <?php
    $db = mysqli_connect(ini_get("mysql.default.user"),
                         ini_get("mysql.default.password"),
                         ini_get("mysql.default.host"));
    
  • 5

    对于极其安全的系统,我们在配置文件中加密数据库密码(配置文件本身由系统管理员保护) . 在应用程序/服务器启动时,应用程序然后提示系统管理员提供解密密钥 . 然后从配置文件中读取数据库密码,解密并存储在内存中以备将来使用 . 仍然不是100%安全,因为它存储在解密的内存中,但你必须在某些时候称它为“足够安全”!

  • 5

    该解决方案是通用的,因为它对于开源和闭源应用程序都是有用的 .

    好处:

    • 你赢了't check your passwords into source control by accident, because you can' t

    • 你赢了't accidentally screw up file permissions. Well, you might, but it won' t影响这个 .

    • 只能由root或该用户读取 . Root无论如何都可以读取所有文件和加密密钥 .

    • 如果使用加密,如何安全地存储密钥?

    • Works x-platform

    • 确保不将envvar传递给不受信任的子进程

    这种方法是Heroku建议的,他非常成功 .

  • 3

    如果可以在存储凭据的同一文件中创建数据库连接 . 内联connect语句中的凭据 .

    mysql_connect("localhost", "me", "mypass");
    

    否则最好在connect语句之后取消设置凭据,因为不在内存中的凭据不能read from memory;)

    include("/outside-webroot/db_settings.php");  
    mysql_connect("localhost", $db_user, $db_pass);  
    unset ($db_user, $db_pass);
    
  • 11

    您的选择有限,因为您说您需要密码才能访问数据库 . 一种通用方法是将用户名和密码存储在单独的配置文件中,而不是主脚本中 . 然后一定要将其存储在主Web树之外 . 那就是如果有一个Web配置问题,你的php文件只是显示为文本而不是被执行,你没有暴露密码 .

    除此之外,您所使用的帐户访问权限最少 . 加上那个

    • 不要将用户名/密码组合用于其他任何内容

    • 将数据库服务器配置为仅接受来自该用户的Web主机的连接(如果数据库位于同一台计算机上,localhost甚至更好)这样即使凭证被公开,除非他们具有其他访问权限,否则它们对任何人都没用 . 机器 .

    • 对密码进行模糊处理(即使ROT13会这样做)如果有人能够访问该文件,它将不会提供太多防御,但至少它会阻止随意查看它 .

    彼得

  • 4

    我认为OP意味着数据库密码 .

    除非有人通过FTP或SSH访问您的服务器(在这种情况下您已经被误导),我不担心在PHP文件中以明文存储密码 . 我见过的大多数PHP应用程序都是这样做的,例如phpbb .

  • 13

    将数据库密码放入文件中,使其对提供文件的用户只读 .

    除非你有一些只允许php服务器进程访问数据库的方法,否则这就是你所能做的 .

  • 3

    如果您使用的是PostgreSQL,那么它会自动查找 ~/.pgpass 中的密码 . 有关更多信息,请参见the manual .

  • 209

    如果你在谈论数据库密码,而不是密码来自浏览器,标准做法似乎是将数据库密码放在服务器上的PHP配置文件中 .

    您只需要确保包含密码的php文件具有适当的权限 . 即它只能由Web服务器和您的用户帐户读取 .

  • 7

    以前我们将DB user / pass存储在一个配置文件中,但后来又变成了偏执模式 - 采用了深度防御策略 .

    如果您的应用程序遭到入侵,则用户将具有对您的配置文件的读取权限,因此有可能让黑客读取此信息 . 配置文件也可以在版本控制中捕获,或者在服务器周围复制 .

    我们已经切换到在Apache VirtualHost中设置的环境变量中存储用户/传递 . 此配置只能由root读取 - 希望您的Apache用户不以root用户身份运行 .

    与此相关的是,现在密码是全局PHP变量 .

    为了降低这种风险,我们采取以下预防措施:

    • The password is encrypted. 我们扩展PDO类以包含用于解密密码的逻辑 . 如果有人读取我们 Build 连接的代码,则使用加密密码而不是密码本身 Build 连接并不明显 .

    • The encrypted password is moved from the global variables into a private variable 应用程序立即执行此操作以减少值在全局空间中可用的窗口 .

    • phpinfo() is disabled. PHPInfo是一个简单的目标,可以概述所有内容,包括环境变量 .

  • 33

    另一个技巧是使用看起来像这样的PHP单独配置文件:

    <?php exit() ?>
    
    [...]
    
    Plain text data including password
    

    这不会阻止您正确设置访问规则 . 但是,如果您的网站被黑客攻击,“require”或“include”将在第一行退出脚本,因此获取数据更加困难 .

    但是,不要让配置文件放在可以通过Web访问的目录中 . 你应该有一个“Web”文件夹,其中包含你的控制器代码,css,图片和js . 就这样 . 其他任何东西都在脱机文件夹中 .

  • 3

    我们用这种方式解决了它:

    • 在服务器上使用memcache,从其他密码服务器打开连接 .

    • 保存到memcache密码(甚至加密的所有password.php文件)加上解密密钥 .

    • 该网站调用memcache密钥保存密码文件密码并在内存中解密所有密码 .

    • 密码服务器每5分钟发送一个新的加密密码文件 .

    • 如果您在项目中使用加密的password.php,则进行审核,检查该文件是否在外部触摸或查看 . 发生这种情况时,您可以自动清理内存,也可以关闭服务器以进行访问 .

相关问题