It's always bothered me that many PHP programs require the user to store the mysql password in plain text (in a string or constant) in a configuration file in the application's root.
Is there any better approach to this after all these years?
So far I have come up with two minimal security boosts:
make the file unreadable via the web using rules in .htaccess (in case php fails or there's a security vulnerability to read php source)
destroy the password in memory after the db connect is made (unset) (to prevent string dumps from a security breach, injection, etc.)
but of course neither of those solve the original problem.
Thanks for any other ideas!
MySQL passwords for users are stored within MySQL itself; they are stored in the mysql. user table. The passwords are hashed by default using the PASSWORD() function, however there are other alternatives, though none are plain-text.
No, the MySQL PASSWORD() function is only used for internal purposes and should not be relied upon. There are hash functions in MySQL but it is a bad idea to do the hashing in SQL. Passwords could easily be exposed through query logs.
The password hashes are stored in the user table of the mysql database. The table files themselves are typically stored in a tree structure under /var/lib/mysql , but that location can be modified by build options or run-time configuration.
Personally, I store sensitive information such as database connection details in a config.ini file outside of my web folder’s root. Then in my index.php I can do:
$config = parse_ini_file('../config.ini');
This means variables aren’t visible if your server accidentally starts outputting PHP scripts as plain text (which has happened before, infamously to Facebook); and only PHP scripts have access to the variables.
It’s also not reliant on .htaccess in which there’s no contingency if your .htaccess file is moved or destroyed.
Caveat, added 14 February 2017: I’ll now store configuration parameters like this as environment variables. I’ve not used the .ini file approach for some time now.
Since your code will need the password there is no perfect security. But you can make it hard to recover.
I put some hash in my web config, as an environment variable, say MYSQL_PASS_HASH
Then I do something like md5(getenv('MYSQL_PASS_HASH').'gibberish$qwefsdf')
which is then the password. Of course you should unsetenv
after that if you're paranoid.
Your password will not literally be stored somewhere, and it can be recovered only when someone has both you web config and your database include.
This happens in a file outside of the webroot (don't put all your trust in .htaccess
).
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