Looking at the structure of most PHP/MySQL-based websites I've seen, it appears that it's not terribly difficult to discern the database password if you dig a bit, as there's invariably a setup or configuration file someplace that stores the information for logging into the DB. Other than the basic precaution of making sure that my database's privileges are appropriately restricted for remote requests, what options are available that I could implement in my own projects to protect this information?
-
1To clarify -- you're asking about storing the credentials to login to the database from the website, and not how to properly store passwords for the website's users within the database, correct?– JoeJan 4, 2011 at 4:19
-
Correct; that's what I'm getting at.– KajiJan 4, 2011 at 4:48
6 Answers
Not a direct answer about storage of the passwords, but I generally use at least two database connections when building webapps -- one's used 99% of the time for user-related activities, with restricted privileges, and the other's used for 'admin' functionality (delete users, etc.).
In a few cases, where I'm installing someone else's package, I'll install two instances ... a public facing instance which only has database access to do the general user-type stuff, and a second instance that's IP-restricted to my local subnet (possibly even on a different machine) that has to be used for any 'admin' type activities. Neither one has access to modify tables, etc, though ... I'd rather go in via the native database tools than allow the webapp to run its own update tasks that haven't been vetted.
You can take it even further though, and add more connections specifically for given tasks ... so the user creation & password management tasks go through a user that has extra privileges on the user tables, login has database privs to authenticate and not much else, etc.
In this way, if there's a sql injection attack, on most webpages it can't really do anything significant -- can't see the password hashes, can't add a new admin user (not that they'd be able to do anything anyway), etc. It still won't help if they manage to get a shell on your machine, but it'll slow them down.
-
1We do something similar. However, we generally create a new account for each user/application of the database instead of doing it by functionality. This solves two problems for us - 1) we can differentiate usage of the database in tools like OEM (ie, we can see who's hammering the database with granularity) and 2) we can individually tailor what each user sees and has access to within the database. Jan 6, 2011 at 16:13
Use One-time passwords, Kerberos, LDAP or whatever else to store your account data and authenticate/authorize users. Directory services are a good means to store user information and use it as a backend to account data.
I'm a big fan of using PostgreSQL's 'Ident' authentication over local sockets whenever I can. That way, local users are mapped directly to the local computer's Unix/Windows users, and I don't have to worry about storing passwords at all. I don't think this is an option in MySQL yet, though.
Where the database and web server are on two separate machines, I use MD5 passwords over SSL: if a hostile has access to my frontend server, it's only a matter of time before he figures out how it communicates with the database.
If you're using the .NET Framework, you can look into using encrypted connection strings. I don't know if such a thing is possible in any other languages/frameworks, but that would be another safeguard to make sure that your connections are not compromised.
Outside of using encrypted connection strings, using LDAP/Kerberos/Active Directory is going to be your safest option.
If your passwords are stored in plain-text, use the hashes (MD5, SHA), Luke!
-
The OP isn't asking about storing user passwords. But yes, certainly hash your user passwords, but never user MD5 or the SHA family to do it! Use bcrypt or PBKDF2. Otherwise you will soon find yourself in the news like these companies that used MD5 and SHA1 and thus exposed their users to simple brute force attacks. Jun 11, 2012 at 19:19
-
Sure, salting and other techniques are required besides just hashing. And one should never implement crypto primitives himself (herself), but rather use some widely tested crypto libraries.– YasirAJun 13, 2012 at 7:53
Depending on your programming language you could encrypt the login credentials, but if you're running an interpreted language then there's no way to ensure that someone can't figure out the credentials if they gain access to the system.
If you're running C++ or the like, then I would recommend you create/find a salted encrypt/decrypt function and run the credentials through that and store the resulting hash as a file on the system.
If you're running PHP or the like, I would recommend you write a wrapper for the mcrypt_encrypt()
and salt the credentials then run some code obfuscation to slow down any hackers if they do gain access to the system.
-
If you encrypt the credentials, you need some other secret to decrypt them again. Or alternatively, the encrypted form becomes the secret, so an attacker could use that. Some details missing. Jan 5, 2011 at 11:29