如何使我的数据库连接安全?

Posted

技术标签:

【中文标题】如何使我的数据库连接安全?【英文标题】:How do I make my database connection secure? 【发布时间】:2011-01-21 16:37:30 【问题描述】:

我目前正在为我教会的大学小组开发一个网站,并且开始有点担心我所写内容的安全性。例如,我使用这个函数:

function dbConnect() 
  
  global $dbcon;

  $dbInfo['server'] = "localhost";
  $dbInfo['database'] = "users";
  $dbInfo['username'] = "root";
  $dbInfo['password'] = "password";

  $con = "mysql:host=" . $dbInfo['server'] . "; dbname=" . $dbInfo['database'];
  $dbcon = new PDO($con, $dbInfo['username'], $dbInfo['password']);
  $dbcon->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  $error = $dbcon->errorInfo();

  if($error[0] != "") 
    
    print "<p>DATABASE CONNECTION ERROR:</p>";
    print_r($error);
    
  

每当我进行某种查询时连接到数据库。我总是使用 PDO 准备语句来防止任何用户输入的 SQL 注入,并且在输出之前使用 htmlspecialchars 进行转义。我的问题是:如何保护我的数据库的用户名和密码?我不知道是否有人可以查看我的 php 文件的源代码,但如果他们可以,我只能想象我会被冲洗掉。我该怎么办?

【问题讨论】:

您对此提出质疑是绝对正确的。 Skilldrick 有正确的答案 - 将敏感数据放在文档根目录之外的文件中。这实际上是我在招聘 PHP 职位时问候选人的一个问题。 这里还有一件事,您正在打印一个数据库错误字符串。我会想出一个不同的日志记录方案,这样在生产环境中你就不会打印这样的信息。它公开了有关您的系统的详细信息。如果它是生产的,请将其记录到系统日志、文件之类的内容中,或者给自己发送一封电子邮件,以便您可以在闲暇时对其进行查看。 是否有人可以指出正确的方向来查找有关如何将文件放在我的 Web 服务器根目录之外的信息? @josh 感谢您的提醒。 无论如何,有些文件将存在于 Web 根目录中。这实际上取决于您的应用程序的结构。最简单的示例是 webroot 中的 index.php,其中包含类似 include("some/dir/outside/of/the/webroot/class.php"); 保护数据库凭据和保护数据库连接是两件不同的事情 - 从长远来看。 【参考方案1】:

您应该将您的数据库凭据放在文档根目录之外的文件中,因此如果出现问题并且您的 PHP 未经解析地显示给用户,那么没有人将能够看到您的密码。

看看this article on the subject this article on the subject:

解决方案很简单。将所有敏感数据放在 Web 服务器的文档根目录之外。许多专家现在主张将大部分(如果不是全部)php 代码放在 Web 服务器的文档根目录之外。由于 PHP 不受与 Web 服务器相同的限制,因此您可以在与文档根目录相同的级别上创建一个目录,并将所有敏感数据和代码放在那里。

【讨论】:

没错。我不会雇用不知道这一点的 PHP 开发人员。 你是说我应该把它放在一个单独的 php 文件中并包含在页面文件中吗?还是完全不同的东西? @Cortopasta:没错,但文件必须位于文档根目录之外。严格来说,您不必包含它:您可以将其作为配置文件读取,但传统上它只是另一个 PHP 文件。 如何在服务器根目录外添加文件? 你们都建议将凭据存储在 wwwroot 之外。好的,我了解安全背景。但是它应该如何存储在版本控制中(示例配置)?通常 wwwroot 是 git repo 的根目录,所以如果外面有任何东西 - 它将在 VC 之外。想象一下新开发人员试图建立一个本地实例进行开发——他怎么会知道“拿这个文件,把它复制到外面然后填写”这样的魔法?【参考方案2】:

好的,这需要澄清一下。有些人建议您将敏感数据放在文档根目录之外。这有一些优点,但实际上比其他任何东西都更安慰剂。

您必须考虑问题的潜在来源。

对计算机具有 shell 访问权限的人会破坏您的数据库连接信息,无论您将其放在何处。这可能包括授权用户和利用漏洞获取 shell 访问权限的用户(这种情况经常发生);

如果 PHP 被禁用或 Web 服务器误以为是这样,那么 PHP 文件可能以原始格式提供。将它们放在文档根目录之外可以保护您免受这种情况的影响;

如果有人以某种方式设法将 PHP 脚本写入文档根目录,则基本上与拥有 shell 访问权限的人相同,因此没有任何措施可以保护您。

实际上,如果您的 Web 服务器受到威胁,那么您的配置文件位于文档根目录之外的情况就不太可能保护您。

数据库安全性的要点是确保来自互联网的人无法直接连接。这可以通过防火墙、将数据库绑定到私有 IP 地址或将数据库放在私有服务器上来完成。

【讨论】:

所以我不会像这样对我的数据库连接进行粗心/不安全的编码吗? @Cortopasta 不,你所做的很标准。 这在您控制主机时有效,但在共享主机中无效。如果您的 Web 服务器设置正确,您能否举例说明您的源代码在 webroot 内部受到威胁的情况?而且您不会以愚蠢的方式存储您的包含(.inc 或其他任何呈现为文本的内容)。 @Josh - 如果是共享主机,那么您无法确保您的网络服务器已(或继续)正确设置。 这是一个悖论,因为您通常无法访问共享主机上的 webroot 之外的内容。人们更经常不小心暴露了他们的 svn 树(在这种情况下,无论哪种方式你都被搞砸了)。在内容类型方面,任何搞砸 apache 配置的人都不应该靠近 conf 文件。我还争辩说,任何有权访问您的源代码的人也可能有权访问该机器,如果是这样,他们无论如何都可以从 webroot 外部读取文件。确保采取其他预防措施(例如 mysql 用户、数据库中的哈希和盐渍敏感数据)。【参考方案3】:

您可以采取一些预防措施。创建一个特定于您的应用程序需要能够执行的操作的 mySQL 用户。这可以限制攻击者在泄露您的用户名和密码时可以造成的损害。例如,允许用户插入、更新、选择等,但不能删除等。此外,正如 cletus 所提到的,外部不应访问数据库。在共享主机环境中,这通常意味着数据库只能从您的 www 服务器或 localhost 连接。

Re: kalpaitch,不要在一些可逆的散列中传递你的密码。人们永远不应该看到您的来源。

【讨论】:

以上是关于如何使我的数据库连接安全?的主要内容,如果未能解决你的问题,请参考以下文章

如何使我的数据库与 TICoreDataSync 保持同步?

默认情况下,条件使用“内连接”而不是“左连接”方法使我的查询工作不是我计划的方式

如何使我的电脑作为主机服务器工作?

从托管在 Heroku 的在线 PHP 站点连接数据库

没有互联网连接时使用 mysql

使我的 SSIS 包可移植 - 如何做到这一点?