I'm wondering what people here use to obscure the username/password they use in their perl scripts to connect to a DB?
If you're really paranoid, don't connect to the database from logic on the web server tier. Instead, connect from middleware that lives on a separate box. Admitedly, this isn't for everyone.
If you're stuck with a one- or two-tier configuration, you have a couple of options. The simple one is to have your script read a username/password from a path that isn't visible to the web server. This works until your box gets hacked.
Another option, available if you're running a two-tier configuration and have some control over the database box, is to user DBI::Proxy and DBD::ProxyServer to the actual database connect to the web server box.
| [reply] |
| [reply] |
if they can get into your server and read your scripts and have any kind of write access (either to modify the scripts or to put their own on the server), you're screwed. nothing you can do.
what we usually worry about is if someone manages to maybe exploit some other script or the webserver is misconfigured and they manage to view the source code of your script. if you've got your passwords hard coded into the script, they'll see them and be able to log into your database and break stuff.
the simple solution is to put your db username/password stuff in a config file and put it outside the webserver's document root.
you could probably come up with a more complicated solution using ssh with public key authentication and port forwarding with the secret key stored in memory and not on disk that would let you set things up so that the user that the webserver runs as could log into the db without a password (and hence it doesn't have to be stored on disk) but that would probably be more trouble than its worth and potentially require that someone is there to enter the password at startup, etc.
anders pearson
| [reply] |
This naturally requires a username/password to connect.
Not necessarily - some rdbms allow external authentication. Eg, OS user 'acct' can access database account 'acct' without specifying a login/password.
This may not seem secure, but imo it's better than having your password in plaintext somewhere.
| [reply] |
Although I've never tried this personally, it seems like the following would be a good solution: First, set up two different database users: The first one, script_user, has read-access to only the users table (no access to other tables), which can look like this:
users:
+----------+----------------+
| username | crypt_pw |
+----------+----------------+
| joe | x47s$EWn47#fdb |
| jane | p98uyDNR93@$w5 |
| ...
while priv_user has read-write access to all tables.
Now the trick is in the crypt_pw column. This is not the hash of the users' passwords, as you may expect -- it is instead the result of a symmetric cipher of priv_user's database password, with each user's password as the key. Obviously generating these columns this must be done beforehand or by some otherwise privileged and "safe" script -- otherwise priv_user's password would have to be hard-coded into some script, making it vulnerable to attacks listed above. You get the point.
So the authentication process will look like this:
- User enters username joe and password in $joe_pw using some authentication scheme (*).
- The script logs into DB using unprivileged script_user and hard-coded password. Since we have read-only access, we are pretty safe hard-coding this password.
- The script gets the crypt_pw value for joe, and deciphers it using his $joe_pw as the cipher key -- this deciphered value is stored in $priv_pw.
- Attempt to relogin to the DB using login priv_user, password $priv_pw. If successful, then $joe_pw was indeed correct as joe's password.
- undef $priv_pw, $joe_pw; to be extra-safe ;)
(*) You can use many methods to achieve step 1. For instance, mod_perl will let you get the password from a HTTP basic authentication request, or you can use a CGI script over SSL, etc. depending on your paranoia level.
Of course, this whole scheme hinges on being able to get 2 DB users, one with with nonstandard permissions -- which isn't always possible at many ISPs. It also makes resetting priv_user's password hard without also resetting the other users' passwords.
Are there any knowledgeable security expert monks out there with critiques of this method? The only hard-coded password would be a "safe" one that is only allows read-only access to a single table. With a strong cipher, you will not be able to determine the password for priv_user without knowing one of the allowed users' passwords. Please share any insights, as my curiosity is piqued by this method.
I hope this helps, and good luck.
blokhead | [reply] [d/l] [select] |
Your method is nice and would be ok in situations where only previously known users can access your application.
As a variation, in the webserver/ISP setting one could think of putting the user/encrypted_password table in a flat file readable from the application. It would avoid the problems with double permissions and under some conditions it would be faster than accessing the database.
One problem I see is that if the attacker can change your application files, it can intercept the cleartext password between steps 3 and 4.
Cheers
Antonio
| [reply] |
Good point, abel! In this fast-paced world of enormous RDBMS systems, we forget about flat files and how elegant they can be in many situations.
blokhead
| [reply] |
Ok, so I've got a similar question as JPaul.
I've got a bunch of users running a DOS app and I'd like to add and modify entries in some MySQL tables on a Debian box under my control each time a user opens and closes a certain file. (The DOS app lets my call out to the shell and run perl and the desired times.) The users' pcs all have Perl installed, along with the DBI and other modules.
Right now the script that connects to MySQL passes the username and password value in plain text and they're hardcoded in the script itself. I'd like to be able to hide these values from the users on the off chance that someone gets curious enough to use them to connect and tinker with the values in the tables.
Any suggestions on where I can stash the username and password values so they won't be visible to the users?
Thanks,
scratch
Homer: And how is education suppose to make me feel smarter? Besides, everytime I learn something new it pushes some old stuff out of my brain. Remember when I took that home wine making course, and I forgot how to drive?
| [reply] |
| [reply] |