Coplan has asked for the wisdom of the Perl Monks concerning the following question:

I'm using DBI to connect to a mySQL database. My connection line looks like this:
my $dbh = DBI->connect('DBI:mysql:database=audic;host=localhost', 'cop +lan', 'password') or die "Can't connect to audic database: $DBI::errstr\n";
In the above statement, "coplan" is my mySQL username, and the password is the password (not really, but you get the idea). I'm curious, though. Is there any way that I can not show a password in this statement? Call me paranoid, but I don't showing any password plain-text, even if the person can't connect to my machine to use mySQL. If I can hide the password, however, it just makes me happier.

--Coplan

Replies are listed 'Best First'.
Re: Hiding DBI Passwords?
by chromatic (Archbishop) on Feb 20, 2001 at 00:33 UTC
    Brian Aker wrote the DBIx::Password module for just this purpose. nate pointed me to it a couple of weeks ago. Could be handy.
Re (tilly) 1: Hiding DBI Passwords?
by tilly (Archbishop) on Feb 19, 2001 at 23:55 UTC
    Move the name/password out of the database and into a configuration file. The nice thing about that approach is that you just use different configuration files in testing and production, and it will automagically connect to different databases with different logins. Also by centralizing passwords it makes it easier to change the password occasionally.

    If you want to have a password that is unavailable to the user running your script, you can make the script setuid and the configuration file only readable to a specific user and group. Whether that makes sense strongly depends upon the specifics of your situation. It does not for me but there are cases where it would be appropriate.

(dkubb) Re: (2) Hiding passwords using DBI's DBI_DSN
by dkubb (Deacon) on Feb 20, 2001 at 10:32 UTC

    I have a lesser known, but very interesting way of hiding a username and password from prying eyes, using only DBI, MySQL and Apache.

    There are a few short steps to the process, but it is well worth it.

    1. Configure your httpd.conf

      Go into your Apache httpd.conf, add the following lines, and restart the web server:

      SetEnv DBI_DSN DBI:mysql:db_name;mysql_read_default_file=/etc/my.cnf

      This will set the DBI_DSN environment variable for all your CGI scripts, globally. The value inside the DBI_DSN variable is used if you do not pass in the first argument to DBI::connect. Any code where you create a DBI handle can now become:

      my $dbh = DBI->connect;
    2. Set your DBI handle attributes

      Before we move on, we will need to make sure of one thing: How do we set any of DBI's attributes? A common method of doing this is:

      my $dbh = DBI->connect( $dsn, $username, $password, { RaiseError => 1, ChopBlanks => 1, Taint => 1 } );

      It is actually possible to include your database handle attributes inside the DBI_DSN, like so:

      DBI:mysql(RaiseError=>1,ChopBlanks=>1,Taint=>1):db_name;mysql_read_default_file=/etc/my.cnf

      Before we go on, you may want to go back and tweak your DBI_DSN inside the httpd.conf using this knowledge.

    3. mysql_read_default_file

      You'll notice that in the DBI_DSN there is an attribute called mysql_read_default_file. This instructs MySQL where the location of the my.cnf configuration is that you'd like to use. The standard name for a MySQL configuration file is my.cnf.

    4. Make your own my.cnf

      Here is a sample /etc/my.cnf MySQL configuration file:

      [client] username=my_username password=my_password

      Inside this file you simply specify the username and password to connect to the database. Make sure you chmod 400 this file, preferably as root, to ensure that no one else can read it.

    That's it, that's all there is to it. In all future CGI scripts don't supply any arguments to DBI::connect, and MySQL will use the defaults you have configured. By utilizing several interesting features of DBI, MySQL and Apache you have now centralized your database and user management, as well as providing a secure storage method for your usernames and passwords.

Re: Hiding DBI Passwords?
by Masem (Monsignor) on Feb 19, 2001 at 23:59 UTC
    If you have apache and mod_perl, you can initialize the DBI in the apache.conf file (which will probably be root.root), as described here. This should be more secure than having it in the cgi files, as now a would-be cracker would have to get root access to get the password, as opposed to possibly coying your web server to give the source to the cgi .pl files.

    Also, some db, (mysql included) use a user's config file that can store the username and password to connect to. A bit more secure particularly if you make sure that the http server's user's home directory is outside the location of the pages to be served.

Re: Hiding DBI Passwords?
by geektron (Curate) on Feb 20, 2001 at 02:58 UTC
    another suggestion nobody's hit on:

    subclass DBI::MySQL to handle the connection phase for you. that way, other developers wouldn't necessarily need to know the password, if that's the concern.

    this solution also makes it easier to handle any encryption you'll probably want to do later on, and requires one change in one place, not tons of changes all over.

    developer code would look more like this:

    #!/usr/bin/perl use MyDBI; my $dbh = MyDBI->db_logon(); # defined in MyDBI, obviously my $sth = $dbh->prepare( 'SELECT * FROM foo ');
    and so on.
Re: Hiding DBI Passwords?
by boo_radley (Parson) on Feb 19, 2001 at 23:47 UTC
    encrypt your uname & password with a scheme that has a perl implementation.
    Note that this is all pseudocode-y ...
    this'll get you something like
    $uname = "asdf332112312adfasdf"; $pass = "wurtqeriotu1231211"; #assume these are encryped, not gibberis +h :)
    then call your script with an extra parameter, the crypt key.
    my $dbh = DBI->connect('DBI:mysql:database=audic;host=localhost', unencrypt_routine ($uname, $key), unencrypt_routine ($pass, $key))
    update did I mention this is off the top of my head? :)

      Bad idea. Anybody smart enough to look in the code to try and find the password will be smart enough to decrypt it.

        Deletia
        update I seem to have misunderstood what was happening, or misrepresented what my original thought on the matter was, or maybe just didn't explain well enough. Your --s have spoken loudly enough, and I will drop the subject...

        updated

Re: Hiding DBI Passwords?
by rrwo (Friar) on Feb 20, 2001 at 01:30 UTC

    Sometimes it's unavoidable. You can move the password to a configuration file, but you still have to worry about the security of that file.

    What you should have is a special login with read-only rights, and only to tables and views used by that script. So if a 'hacker' gets the username and password, there should be nothing compromised except the information that can normally be gotten from running the script. (Depending on what the script does, there may still be too much information to divulge to just anyone in the database.)