Search code examples
mysqlpdoconnection

Securing PDO connection strings for MySQL


I'm just learning PDO and need to know if this connection (it works) is really secure. I put my connections in an inaccessible folder outside of the root.

Is this well formed or can I improve it?

Do I need the $conn->setAttribute...EXCEPTION?

$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();
}

Solution

  • if this connection (it works) is really secure.

    Not quite.

    You are revealing a database error to the whole world. And it could contain some sensitive details such as database structure. One can call it anything but secure.

    Do I need the $conn->setAttribute...EXCEPTION?

    Yes but that's a bit irrelevant.

    can I improve it?

    You are assigning only the username and password to variables. What about the database? Other configurable stuff?

    But in the first place you should really avoid echoing the database error information. As a rule, you just shouldn't catch an error of this level. It should just let your application die. However, in this particular case of a database connection error, the stack trace would contain the database credentials and you don't want to see them even in the error log, least displayed on the screen. Hence, you got to catch this error and then throw a brand new exception that wold contain only the message but not the stack trace.

    $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());
    }
    

    This way, in case of the connection error we will have a proper exception, but without any sensitive details such as database password. And this exception, in turn, will be hanlded according the the site-wide configuration - either displayed on screen, logged, or handled by a dedicated error handler.

    As of the configuration options, they can be detached and stored in some configuration file.