Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Obscuring sensitive data in Perl code?

by larryl (Scribe)
on Mar 10, 2001 at 00:37 UTC ( #63347=perlquestion: print w/replies, xml ) Need Help??
larryl has asked for the wisdom of the Perl Monks concerning the following question:

Can anyone share any good schemes for obscuring login IDs, passwords and the like where they get used in Perl code? For example in a <Perl> section of a mod_perl-enabled Apache config file, or in a DBI connection to Oracle like:

$user = 'scott'; $passwd = 'tiger'; $dbh = DBI->connect("dbi:Oracle:somedbname", $user, $passwd);

Not expecting anything bulletproof, just something enough that the casual observer wouldn't notice while poking around in a filesystem.


Replies are listed 'Best First'.
Re: Obscuring sensitive data in Perl code?
by chromatic (Archbishop) on Mar 10, 2001 at 01:19 UTC
    See DBIx::Password, which exists precisely for that purpose.

    Have the system administrator restrict its access to the user under which Apache/mod_perl run, ie 'www' or 'nobody'.

Re: Obscuring sensitive data in Perl code?
by merlyn (Sage) on Mar 10, 2001 at 00:42 UTC
    Don't put them in the source. Put them in a separate file, and pull in that file. Then be very careful whom you show that file to.

    -- Randal L. Schwartz, Perl hacker

      ++, but still, what is to stop someone from doing this to the original script: (pseudo-code)...
      my $db_password = get_password("filename"); print $db_password; # someone could insert this... my $dbh = DBI->connect(.....);
      I don't think there is any way around this is there? Security through obscurity (while obviously bad for other reasons) falls down on this issue too.

      $ perldoc perldoc

      Hmmm, I've been down that train of thought before, but it seems that it just delays the inevitable (Oh look, the account info is being read from a file - I'll go have a look at that file...). Anyone with access to the secondary file will be able to figure it out. But thanks for your suggestion - at least then the code by itself could be shown to others (for review, etc.) without exposing anything.

      I think I'll go snag something I can adapt from the Obfuscated Code page, stick it in a module, and hope for the best...

        I think I'll go snag something I can adapt from the Obfuscated Code page, stick it in a module, and hope for the best...
        Uh, no. That's precisely the wrong route. Security through obscurity. Check it out on google. Bad idea.

        Just treat that second file as sacred. Don't let people get at it.

        -- Randal L. Schwartz, Perl hacker

        To spell it out more explicitly...

        Make your program setgid and make it owned by a new group such as "wwwpass". Hide your database username/password combo in a separate file which can only be read by the group "wwwpass".

        Now only your program can read the file. Before it does, have your program authenticate the user somehow. If this authentication fails, just terminate the program. If it passes, go ahead and read the sensitive data from that external file.

        This way, even if a user finds out where the sensitive data is hidden, he can't read it unless he uses your program and passes your authentication test.

        You can use setuid instead of setgid if you must, but I personally feel safer using setgid and using a new group name which is dedicated to this task alone.

        The only drawback to all of this is that you must now ensure that your program will pass "taint" checks. But is that really a drawback?


        why should they have access to the secondary file??
        If you're on a server, you can easily set permissions for files, and you can put the file somewhere unreachable by others without proper permission.

        As you can encrypt the passwords

        Chady |
Re: Obscuring sensitive data in Perl code?
by Tuna (Friar) on Mar 10, 2001 at 00:42 UTC
    would this help to point you in the right direction?
Re: Obscuring sensitive data in Perl code?
by reyjrar (Hermit) on Mar 10, 2001 at 01:14 UTC
    You could also use Getopt::Std and have a -u username -p password option.
    what I typically do, is while I'm developing I'll:
    my $USERNAME = $OPTS{'u'} || "username"; my $PASSWORD = $OPTS{'p'} || "password";
    then once I move it into production I'll take out the "|| 'username'"'s and add checks for the username/password in the code and die if they're not there. Unfortunately though, you have to have your passwords decrypted in plain text somewhere.

    When I do things with DBI, I use the database privileges system to give JUST enough rights to the user that my scripts can do what they need from where ever. As an example, lets say I have a database "network" and a table "devices" and I just need my script to get information from that database. I know my script is running on then I can (in MySQL)
    GRANT SELECT ON network.devices TO script@; FLUSH PRIVILEGES;

    and while you might not be administering this database, any good DBA will work with you to grant your script user _JUST_ the privileges it needs to do whatever it has to do.

    This isn't possible with DBI but things like ssh have "publickey authenication" so you might want to sniff around for information on varying authentication methods.. If you're logging into a linux server, you might wanna read up on Pluggable Authentication Modules (PAM).

    just a few ideas..

      Eek! Bad idea. If you specify your password with -p, anyone on the system can probably see it with `ps`.
        not with a secured /proc filesystem ;) only root could see it..
Re: Obscuring sensitive data in Perl code?
by turnstep (Parson) on Mar 10, 2001 at 03:00 UTC

    You could also use environment variables. That way, it wouldn't matter who saw your script:

    my $user = $ENV{ORACLE_USER}; my $passwd = $ENV{ORACLE_PASS}; my $SID = $ENV{ORACLE_SID}; my $dbh = DBI->connect($SID,$user,$passwd,{PrintError=>0, AutoCommit=> +0}) or die "Could not connect to $SID: $DBI::errstr\n";

    This also allows you to change the instances, usernames, passwords, etc. without having to edit your script.

      Eeek.......! Using environment variables for sensitive data is bad, bad, bad!!!!!!!
      type env at a prompt and wala...out pops the data!!!!!
      (__) (\/) /-------\/ / | 666 || * ||----||

        Yes, but if you someone already has shell access to *that* account, then there is already a bigger problem. If I create a script like the above, and make it chmod 755, nobody is going to get the sensitive data unless they are logged in as me, althought anyone can read (and run) the script themselves. You can even use very restricted accounts (e.g. no shell access) for more security. The point is, you completely separate the sensitive data from the script. I like this particular way because I can do something like this in .bashrc:

        alias oradev='export ORACLE_SID=dev; export ORACLE_PASS=foo; \ export ORACLE_PASS=bar; echo Set instance to development'

        ...which allows easy interchange of instances, passwords, and other parameters from the command line. Nothing wrong with setting good permissions on an included file, either, but if you can run/read the script, you can track down and read the passwords.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://63347]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2017-05-29 21:47 GMT
Find Nodes?
    Voting Booth?