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"));
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!
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
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.
I have now wrapped my connection in a try/catch block, but still I think this is catastrophic!
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?
The connection remains active for the lifetime of that PDO object. To close the connection, you need to destroy the object by ensuring that all remaining references to it are deleted—you do this by assigning null to the variable that holds the object.
PDO gives you the option of handling errors as warnings, errors, or exceptions. However, when you create a new PDO connection object, PDO always throws a PDOException object if an error occurs.
To standardize and streamline development practices, PHP introduced PHP Data Objects (PDO) in PHP 5.1. These objects are used to setup PDO database connections. PDO is a database access layer which provides a fast and consistent interface for accessing and managing databases in PHP applications.
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.
Yes, you should also have it in a try/catch block.
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.
A simple workaround is to catch the PDOException thrown by the PDO constructor:
try { $dbh = new PDO('mysql:host=localhost;dbname=DB;port=3306', 'USER', 'SECRET', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")); } catch (PDOException $e) { throw new Exception($e->getMessage()); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With