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

I already asked this question... but from the responses I got (Hiding the pass in a DBI script) and research I did, I found that I didn't exactly get the answer I wanted, so I will ask again in a different style.

The question is about DBI, and having passwords in the script. It seems a bit of a problem for bigger systems. If you have a perl system script and want to allow users to use it, they need read priviledges, which allows them to see the password, yes?

Someone mentioned the DBIx modules, which almost do what you want, but not really, since they don't prevent other users from using your virtual user in the same way, and still having access to the database.

So I am wondering if we perl monks in all our glorious perl light can come up with something (other than suid wrappers for the perl script, which would work... but is overkill and possibly a security hole) to fix this. I thought of a system to request the password from another program, based on the script location... I.E. /usr/bin/foo may access this password, but no one else... unfortunately, I can't seem to find a foolproof way for verifying the name of a script.
Does anyone else have ideas? It seems like a valid project, and if it could be implemented right, it could have uses in other places as well...

Of course, I may also be missing some fundamentally simple solution, too, but I'll never know until I ask, will I?
                TIA - Ant

Replies are listed 'Best First'.
Re: Hiding passwords in scripts...
by merlyn (Sage) on Apr 13, 2001 at 19:29 UTC
    You're not missing anything. If someone has access to the script source, and can run another script in the same environment, it doesn't matter what you do: they'll be able to determine the password.

    So, you need to prevent one or more of those conditions. Either don't give them access to the source (or the sources being pulled in), or don't give them the ability to run a program in the same environment.

    -- Randal L. Schwartz, Perl hacker

      So, there is no way to tell for sure the location of the script calling you... doesn't surprise me, would be nice, though. Since then people could run the script but their own script wouldn't work with it....

      Too bad you can't make perl script 711 like compiled binaries...

      Although... here's an idea... you can make c binaries executable but not readable... correct? maybe a compiled c binary that contained the password, and basically just ran a sscript via the system call... passing the password in... ummm... ARGV and env are both accessible through like... /proc aren't they... what is the best way? Because then you could have a nice generic C source, feed it the data you want added in, and still have the perl script run as the user and not suid. Not sure this is right, but it sounds promising...
                      - Ant

Re: Hiding passwords in scripts...
by tadman (Prior) on Apr 13, 2001 at 19:35 UTC
    Apart from a suid script, which is really the only way to do this "properly", there are few options that will actually work to the same degree.

    I can only assume that you are concerned about 'shell-level' access to the database, and not through the Web in particular. As such, you want to prevent the average user from discovering the DB password, such that they can connect to the DB and do all sorts of horrible things to it, outside the scope of the script(s) which are presumably safe.

    The reality is that if the user's Perl interpreter can read the script, and the associated password, then there is little you can do to prevent it from being discovered. You can obfuscate it a bit (i.e. 'perlcc' plus some tricks to prevent a plain-text attack), but that only buys you limited time from a determined cracker. If the script can't read the password, it can't access the DB.

    If it's applicable, you might want to move your application to a Web based format, such that the users don't have direct access to the system. This will go a long way to preventing unauthorized activity.

    As a cheaper alternative, you may be able to restrict 'shell' access by setting their login shell to be the application. Historically, though, it is easy to escape from this kind of restriction using something as simple as ':shell' in vi, so some care will have to be taken when testing.
      Basically system stuff on systems where people are allowed shell access...

      For ISPs, depending on their setup, web based isn't the best, necessarily... If they aren't set up with suexec or something similar, though I guess they probably should be, still.. on a shell system it's not as simple as suexec...
                      - Ant

        On a shell system, you can have a gateway 'suid' program that controls access to your application/module. You have to be careful about '-T'aint checking when you do this, though, to avoid being exploited.
        #!/usr/bin/perl -wT use strict; use MyModule; # Your important module(s) # Now do something as the suid user MyModule::DoSomething();
        Then set it to -rwsr-xr-x suid:     % chmod 4755 theprogram
Re: Hiding passwords in scripts...
by Desdinova (Friar) on Apr 13, 2001 at 20:43 UTC
    Persoanlly for me I try not to put passwords in scripts. There really is no way to keep that secure. If the DB needs a password to access, I make the user type the password.
    I create a user in the database and give that user only the access they need at the DB level. That keeps them from doing any real damage or at least there is a link between the damage they can do how much they are trusted. If for whatever reason you need to place a password in the script do it with a very limited DB user. If you provide permission in a database for user to drop whole tables, they will it might be due to meanness, or user error or even your script messing up.

    As general guide when i plan security i take the approach of giving the user only what they need to get the work done, including myself.
      The main thrust of this is for system scripts that do things like insert into the DB, so having them type the passwd really won't work...
                      - Ant
Re: Hiding passwords in scripts...
by kschwab (Vicar) on Apr 13, 2001 at 19:52 UTC
    Another option is to create a new user, chown the script to that user, chmod the perl script to 0700, and use something like sudo or super to run the script as that uid.

    This is perhaps not a great solution if the script needs to create or read files owned by the person invoking it.

Re: Hiding passwords in scripts...
by $code or die (Deacon) on Apr 14, 2001 at 01:56 UTC
    I would say that the best scenario would be simply good security practice -
    • Restrict access to where the password is stored
    • Keep the password known to as few people as possible
    • Choose a strong password
    • Change it very frequently
    • Don't use the same password for all systems

    I know this isn't the answer you want, but I don't think there is another way. No matter where you store your password, you could be bitten by someone - external or internal.
    $ perldoc perldoc