Unable to suppress PDO Exception (reveals user/pass)

One of my DB servers went down momentarily and my production site started spewing out PDO SQL Exceptions with full stack trace including password. I have set the database options as:

$db = new Db\Adapter\Pdo\Mysql(array(
    'username' => 'root', 
    'password' => 'hello',
    'dbname' => 'test',
    'options' => array(
         PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT
    )
));

I have also set the following which works fine for all other errors except PDO:

ini_set('display_errors', 0);

Despite this, when one of my DB servers went down momentarily, my production site started showing the full exception and password:

string(94) "SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known"
object(PDOException)#86 (8) {
  ["message":protected]=>
  string(94) "SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known"
  ["string":"Exception":private]=>
  string(0) ""
  ["code":protected]=>
  int(2002)
  ["file":protected]=>
  string(53) "/var/www/www.dawn.com/apps/shared/config/services.php"
  ["line":protected]=>
  int(86)
  ["trace":"Exception":private]=>
  array(11) {
    [0]=>
    array(4) {
      ["function"]=>
      string(11) "__construct"
      ["class"]=>
      string(3) "PDO"
      ["type"]=>
      string(2) "->"
      ["args"]=>
      array(4) {
        [0]=>
...
    [1]=>
    array(4) {
      ["function"]=>
      string(7) "connect"
      ["class"]=>
      string(22) "Phalcon\Db\Adapter\Pdo"
      ["type"]=>
      string(2) "->"

Am I missing something or is this a Phalcon bug? All suggestions welcome.



33.7k
edited Sep '14

Hey

Can you try

 new Db\Adapter\Pdo\Mysql(array(
         'host'     => $di->get('config')->database->host,
        'username' => $di->get('config')->database->username,
        'password' => $di->get('config')->database->password,
        'dbname'   => $di->get('config')->database->dbname,
        'schema'   => $di->get('config')->database->schema,
        'options'  => array(
            \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $di->get('config')->database->charset
        )
    ));


5.3k

@Duy, that didn't work. This appears to be a Phalcon bug I presumse. Have filed an issue https://github.com/phalcon/cphalcon/issues/2764

edited Sep '14

Why not try/catch your main bootstrap file?

<?php

try{
    $di = new Phalcon\DI();
    //Main bootstrap code
    //etc etc

} catch(\PDOException $e){
    //Do something...

} catch(\Phalcon\Exception $e){
    //Do something...

} catch(\Exception $e){
    echo "Exception: ", $e->getMessage();
    if(isset($di) && $di->get('logger')){
      $di->get('logger')->error($e);
    }
}

I don't think the overall issue is Phalcon, but moreso specifically your environment. Do you have the PHP Module 'xdebug' loaded by any chance?



5.3k

Mitchell, I don't have xdebug loaded and yes I have resorted to try/catch but that's not the point I am after. It's that Phalcon is not obeying the PDO options for silencing failures (yes, silencing failures is a bad choice and it is better to catch and log these exceptions).

Exceptions should not bubble up to the end user in production even if they are uncaught.

Exceptions should be logged to the error log. PDO exceptions are handled separately and it is documented that despite the display_errors settings and error level settings, they will bubble up to the user unless you supress or catch them. I did supress them using the silent flag but the flag was not obeyed by Phalcon which documents that PDO options are passed to the PDO constructor. So it appears to be a bug.