Alexey Skripnik Wed Oct 05 13:05:17 -0400 2011

Subject: PHP-AR show my MySQL login and password in errors!

Hi, guys. Something happened with my MySQL server and i saw error contains my login and password:

Uncaught exception 'ActiveRecord\DatabaseException' with message 'exception 'PDOException' with message 'SQLSTATE[HY000] [1129] Host '***' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'' in /home/***/activerecord/lib/Connection.php:239 Stack trace: #0
/home/***/activerecord/lib/Connection.php(239): PDO->__construct('mysql:host=brie...', 'MY_LOGIN', 'MY_PASSWORD', Array) #1

It's good that it happened in closed beta project, but when i'll open my website and if my MySQL server will fall again, users can show my login and password. Can somebody explain me, how to fix this security hole?

P. S. Sorry for my English.


Clay vanSchalkwijk Wed Oct 05 13:14:28 -0400 2011

You need to catch that exception when you're setting up your connection.

Alexey Skripnik Wed Oct 05 13:33:37 -0400 2011

try {
$cfg->set_model_directory(…);
$cfg->set_connections(…);
} catch (Exception $e) {
echo 'Error!!!';
}

Clay, something like that?

Alexey Skripnik Wed Oct 05 13:41:57 -0400 2011

OMG! I'm not alone. Look, it's heaven for hackers: http://www.google.com/search?q=activerecord+%22PDO-%3E__construct('mysql%3Ahost%3D%22

Dear developers of PHP-AR, please, defense your users from this security issue.

Max Schwanekamp Wed Oct 05 17:29:15 -0400 2011

Dude! Catch the exception and the problem is solved. The fact that all those others fail to do so is not the devs' fault.

Alexey Skripnik Tue Oct 25 08:35:54 -0400 2011

I'm trying to catch the exception, but it doesn't works. What do i wrong? How to fix it?

ActiveRecord\Config::initialize( function($cfg) {
$cfg->set_model_directory(...);
try {
$cfg->set_connections(...);
} catch (DatabaseException $e) {
echo 'FFFFUUUUUUUU!!!!!!!!!!!!!';
}
});

Max Schwanekamp Tue Oct 25 21:20:13 -0400 2011

ActiveRecord\Config::set_connections() throws a ConfigException, not a DatabaseException.
All AR exception classes derive from ActiveRecordException, So if you want to be sure you catch it, do something like:
try { ... }
catch (ConfigException $e) { ... }
catch (ActiveRecordException $e) { ... }

Also about that "security hole": you shouldn't be outputting your errors to the user in a production system, regardless of whether the errors are from PHP-AR or not. display_errors directive should be set to false in php.ini or at least in .htaccess (or equivalent). Use a logger to record your system errors.

HTH.

Mikkel Schmidt Sat Nov 19 23:23:55 -0500 2011

Just for the record, you are missing the ActiveRecord\ namespace in your catch block. Try this:

 1 ActiveRecord\Config::initialize( function($cfg) {
 2     $cfg->set_model_directory(...);
 3     try {
 4         $cfg->set_connections(...);
 5     } catch (ActiveRecord\DatabaseException $e) {
 6         echo "Database error";
 7     } catch (ActiveRecord\ConfigException $e) {
 8         echo "Config error";
 9     }     
10 });

And as Max said, you should really disable errors in a production environment. If you don't want to do that (you should) you can surround the initialization of your application with a try catch block that catches everything:
1 try {
2     # Initialize application
3 catch (Exception $e) {
4     # Do custom error handling
5 }

(1-7/7)