为什么连接失败时 PDO 会打印我的密码?

2022-01-24 00:00:00 connection security php mysql pdo

我有一个简单的网站,我使用 PDO 建立与 MySQL 服务器的连接.

I have a simple website where I establish a connection to a MySQL server using PDO.

$dbh = new PDO('mysql:host=localhost;dbname=DB;port=3306',
               'USER',
               'SECRET', 
               array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

我的网站有一些流量,并且达到了服务器的连接限制,网站抛出了这个错误,里面有我的 plain 密码!

I had some traffic on my site and the server's connection limit was reached, and the website throws this error, with my plain password in it!

致命错误:未捕获的异常带有消息的PDOException"'SQLSTATE [08004] [1040] 太多连接'在/home/domain/html/index.php:xxx堆栈跟踪:#0/home/domain/html/index.php(64):PDO->__construct('mysql:host=local...',用户"、秘密"、数组)#1{main} 投入/home/domain/html/index.php 上第 64 行

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[08004] [1040] Too many connections' in /home/domain/html/index.php:xxx Stack trace: #0 /home/domain/html/index.php(64): PDO->__construct('mysql:host=loca...', 'USER', 'SECRET', Array) #1 {main} thrown in /home/domain/html/index.php on line 64

具有讽刺意味的是,出于安全原因我切换到 PDO,所以这真的让我感到震惊,因为在大多数网站上,使用简单的 HTTP 泛洪很容易引发这个确切的错误.

Ironically I switched to PDO for security reasons, so this really shocked me, because this exact error is something you can provoke very easily on most sites using simple HTTP flooding.

我现在已经将我的连接包装在一个 try/catch 块中,但我仍然认为这是灾难性的!

I have now wrapped my connection in a try/catch block, but still I think this is catastrophic!

我是 PDO 的新手,所以我的问题是:我必须做些什么才能确保安全?如何以安全的方式建立连接?是否还有其他我必须注意的已知安全漏洞?

I am new to PDO and so my question is: what do I have to do to consider to be safe? How do I establish a connection in a secure way? Are there other known security holes like this one that I have to be aware of?

推荐答案

无论如何,您应该在 PHP.ini 中添加 display_errors = off 以避免此问题.除了 PDO 之外,揭示此类细节的错误还来自许多地方.

You should have display_errors = off in your PHP.ini anyway to avoid this problem. Errors that reveal details like these come from many places, in addition to PDO.

是的,您还应该将它放在 try/catch 块中.

Yes, you should also have it in a try/catch block.

您也可以$pdo->setAttribute(PDO::ERRMODE_SILENT),但是您需要手动检查错误代码,而不是使用 try/catch 块.请参阅 http://php.net/manual/en/pdo.setattribute.php 更多错误常量.

You can also $pdo->setAttribute(PDO::ERRMODE_SILENT), but then you need to be checking the error codes manually rather than using a try/catch block. See http://php.net/manual/en/pdo.setattribute.php for more error constants.

相关文章