【问题标题】:Securing PDO connection strings for MySQL保护 MySQL 的 PDO 连接字符串
【发布时间】:2014-04-13 00:27:09
【问题描述】:

我刚刚学习 PDO,需要知道这种连接(它有效)是否真的安全。我将我的连接放在根目录之外的一个无法访问的文件夹中。

这是正确的还是我可以改进它?

我需要$conn->setAttribute...例外吗?

$user = 'JoeUser';
$pass = 'JoesPassword';

try {
  $conn = new PDO("mysql:host=myWebHost.com;dbname=MydataBase", $user, $pass);
  $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} 
catch(PDOException $e) {
  echo 'ERROR: ' . $e->getMessage();
}

【问题讨论】:

  • 安全与否,取决于您的安全要求。由于您的密码以纯文本形式存储,因此任何有权访问服务器的人仍然可以读取密码。阅读:stackoverflow.com/questions/97984/…
  • 好文章推荐。这实际上是在 ssl 上。你是说,即使它位于公共文件夹之外,我仍然应该将我的用户名和密码放入一个单独的文件中,并使用 include.php 将它们带入?
  • 把你的密码写在一个配置文件里,然后把文件放在网络根目录和源代码管理文件夹之外,对于一般实践来说已经足够了。

标签: mysql pdo connection


【解决方案1】:

如果这个连接(它有效)真的很安全。

不完全是。

您正在向全世界揭示一个数据库错误。它可能包含一些敏感的细节,例如数据库结构。可以称它为安全的任何东西。

我需要 $conn->setAttribute...EXCEPTION 吗?

是的,但这有点无关紧要。

我可以改进它吗?

您仅将用户名和密码分配给变量。数据库呢?其他可配置的东西?

但首先你应该避免回显数据库错误信息。通常,您不应该捕获此级别的错误。它应该让你的应用程序死掉。但是,在这种数据库连接错误的特殊情况下,堆栈跟踪将包含数据库凭据,您甚至不希望在错误日志中看到它们,在屏幕上显示的最少。因此,您必须捕获此错误,然后抛出一个全新的异常,该异常仅包含消息但不包含堆栈跟踪。

$user    = 'JoeUser';
$pass    = 'JoesPassword';
$host    = 'myWebHost.com';
$db      = 'MydataBase';
$charset = 'utf8mb4';

try {
    $conn = new PDO("mysql:host=$host;dbname=$db;charset=$charset", $user, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

这样,在连接错误的情况下,我们将有一个适当的异常,但没有任何敏感的细节,如数据库密码。反过来,此异常将根据站点范围的配置进行处理 - 显示在屏幕上、记录或由专用错误处理程序处理。

对于配置选项,它们可以分离并存储在一些配置文件中。

【讨论】:

  • 好吧,天哪,爸爸,我很欣赏这些信息,但是,这次真的需要桨吗?保证,以后不会了。 :-) 老实说,感谢您的调整。我正在努力处理所有这些新信息,有时需要好好打一巴掌。
  • 但是删除 try-catch 现在可能会显示数据库密码的前 16 个字符(如果 PDO 构造函数失败,例如 "getaddrinfo failed: Temporary failure in name resolution" )?也许添加一些关于这些场景的细节(或参考)以及如何避免它们?相关问题:Why does PDO print my password when the connection fails?
  • @PeterMortensen 谢谢,我正在编辑答案以解决这个问题:)
【解决方案2】:

它本身很好,但请记住,应用程序的不安全部分可能会改变这一点。如果您在应用程序中调用了任何文件访问方法并且没有足够的输入清理,那么即使是根目录之上的内容有时也会被攻击者读取。

您需要确保该文件的权限受到适当限制,尤其是当您在共享主机上时。

错误模式对于您的要求不是必需的,但我还是推荐它。

不推荐使用catch中的简单echo。尝试设置一个可以作为开发人员监控的错误/异常记录系统。简单地将原始错误消息写入页面是不安全且不专业的。

请将所有代码封装在类中。全局作用域变量是一场噩梦,全局作用域代码会让你的生活变得更艰难。

【讨论】:

  • 感谢汉斯的帮助。在接下来的几天里,我也会阅读更多关于您的建议的内容。一遍又一遍。
猜你喜欢
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2023-03-29
  • 2010-10-20
  • 2013-05-26
  • 1970-01-01
相关资源
最近更新 更多