Admin CGI and password security?

B

Bill

I am working on a package of perl CGI scripts, which are to be as
secure as practicable for stuff that is on a public server :).

One of the scripts is an administrative script, which allows users (of
which there are two security level classes, with the higher level
class able to create users at the lower level) to be added or
modified.

In order to start the package going, at least one administrator
account must be created, or already exist, at installation time.

One way to do this is to have a line in the administrator script that
is modified to create an administrator, for example:
edit
my %admin; to be
my %admin = ( 'admin' => 'Mybig0leNastypassword' );

However, I am concerned that this exposes a plaintext admin account in
the CGI text, even though it would not be readable by regular HTML
access. Regular user passwords, as they are added, will be put in a
database as a SHA1 digest.

Does anyone know of a better way to do this in Perl? I'd rather not
have the security hole of a default admin account at time of startup.
 
D

David K. Wall

Bill said:
I am working on a package of perl CGI scripts, which are to be as
secure as practicable for stuff that is on a public server :).

One of the scripts is an administrative script, which allows users (of
which there are two security level classes, with the higher level
class able to create users at the lower level) to be added or
modified. [snip]
Does anyone know of a better way to do this in Perl? I'd rather not
have the security hole of a default admin account at time of startup.

The usual method is to store an encrypted password somewhere. When a user
enters a password, it is encrypted and then compared to the stored encrypted
password. See 'perldoc -f crypt'.
 
R

Robin

Bill said:
I am working on a package of perl CGI scripts, which are to be as
secure as practicable for stuff that is on a public server :).

One of the scripts is an administrative script, which allows users (of
which there are two security level classes, with the higher level
class able to create users at the lower level) to be added or
modified.

In order to start the package going, at least one administrator
account must be created, or already exist, at installation time.

One way to do this is to have a line in the administrator script that
is modified to create an administrator, for example:
edit
my %admin; to be
my %admin = ( 'admin' => 'Mybig0leNastypassword' );

However, I am concerned that this exposes a plaintext admin account in
the CGI text, even though it would not be readable by regular HTML
access. Regular user passwords, as they are added, will be put in a
database as a SHA1 digest.

Does anyone know of a better way to do this in Perl? I'd rather not
have the security hole of a default admin account at time of startup.

it's crypt I think... although I don't know anything about that function,
look it up.
 
P

pkent

In order to start the package going, at least one administrator
account must be created, or already exist, at installation time. ....
However, I am concerned that this exposes a plaintext admin account in
the CGI text, even though it would not be readable by regular HTML

What I'd do is not store the password but store a hash of the password.
A simple example is in 'perldoc -f crypt' but note that the hashing used
by crypt is not thesedays considered secure against a brute force
attack, so I would recommend you look at some of the stronger hashing
algorithms on CPAN. (SHA1 springs to mind but you should investigate the
strengths of various ones).

I'd guess that you want to use https to prevent people from snooping the
password being sent from the browser to the CGI, and possibly to make
man-in-the-middle attacks harder but I don't know about that so ask an
expert. Maybe you can add other measures, such as remote IP address
checks, to add some extra protection.

[ If you don't know: a hash is a one way function - you cannot recover
the plaintext from the hash. This is why Unix passwords are stored in
hashed form. However you can apply the same hash to the password that
the user types in and see if the hashed version of their input matches
the _saved_ hashed version of the password. ]

P
 
B

Bruce Horrocks

Bill said:
In order to start the package going, at least one administrator account
must be created, or already exist, at installation time.

Can you not have the script remove the default account once the first
proper admin account has been created? If anyone does somehow get access
to the source subsequently it won't matter because the default account
will no longer exist.

Regards,
 
B

Bill

Bruce said:
Can you not have the script remove the default account once the first
proper admin account has been created? If anyone does somehow get access
to the source subsequently it won't matter because the default account
will no longer exist.

Regards,

I guess this is the way to go. The admin script will have a default
password, but this can ONLY be used if there are no other admin
accounts, and it only serves then to create a real admin account and
then log off.

The created admin accounts are the only ones allowed to do other admin
things.

Anyone see holes in this one? I'm also looking at optional
client-IP-based restrictions, a la Webmin.

--Bill
 
J

James Willmore

I am working on a package of perl CGI scripts, which are to be as
secure as practicable for stuff that is on a public server :).

One of the scripts is an administrative script, which allows users (of
which there are two security level classes, with the higher level
class able to create users at the lower level) to be added or
modified.

In order to start the package going, at least one administrator
account must be created, or already exist, at installation time.

One way to do this is to have a line in the administrator script that
is modified to create an administrator, for example:
edit
my %admin; to be
my %admin = ( 'admin' => 'Mybig0leNastypassword' );

However, I am concerned that this exposes a plaintext admin account in
the CGI text, even though it would not be readable by regular HTML
access. Regular user passwords, as they are added, will be put in a
database as a SHA1 digest.

Does anyone know of a better way to do this in Perl? I'd rather not
have the security hole of a default admin account at time of startup.

I'd use one of the many Crypt modules for this - regardless of the type of
account. You could use a file checksum as the key that's required for the
module you decide to use.

This *may* get you started.

That's my $0.02

HTH

--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
What I want is all of the power and none of the responsibility.
 
B

Bruce Horrocks

Bill said:
Anyone see holes in this one? I'm also looking at optional client-IP-
based restrictions, a la Webmin.

Having thought about it a bit more, I'd suggest that you do both: use
Crypt *and* delete the account once it has served its purpose.

Enter and run the following bit of code:

use strict;
use warnings;

use Crypt::Salt;
BEGIN { $Crypt::UnixCrypt::OVERRIDE_BUILTIN = 1 }
use Crypt::UnixCrypt;

print "Encrypted admin password is: ",
crypt('mytough123password', salt()),
"\n";

This will print a line something like:

Encrypted admin password is: fGXFJz0d1fMuI

Now, in your script, use the following snippet to check to see if the
correct password was entered:

if (crypt($entered_password, 'fG') eq 'fGXFJz0d1fMuI') {
# Password is okay
}

Voila, your password no longer appears as plaintext in your script.

Note the string 'fG' in the salt parameter to the crypt function. This
must be the first two characters of the encrypted password.

You should still delete the temporary admin account afterwards because
someone who obtains the source code could brute-force the password.

Regards,
 
B

Bill

Bruce said:
Having thought about it a bit more, I'd suggest that you do both: use
Crypt *and* delete the account once it has served its purpose.


Enter and run the following bit of code:

use strict;
use warnings;

use Crypt::Salt;
BEGIN { $Crypt::UnixCrypt::OVERRIDE_BUILTIN = 1 }
use Crypt::UnixCrypt;

print "Encrypted admin password is: ",
crypt('mytough123password', salt()),
"\n";

This will print a line something like:

Encrypted admin password is: fGXFJz0d1fMuI

Now, in your script, use the following snippet to check to see if the
correct password was entered:

if (crypt($entered_password, 'fG') eq 'fGXFJz0d1fMuI') {
# Password is okay
}

Voila, your password no longer appears as plaintext in your script.

Note the string 'fG' in the salt parameter to the crypt function. This
must be the first two characters of the encrypted password.

You should still delete the temporary admin account afterwards because
someone who obtains the source code could brute-force the password.

Regards,

This is actually moving even more toward general CGI security issues and
away from Pure Perl, but for all those who suggested Crypt, I'm already
set up to use Crypt::SHA1 for passwords and use Crypt::Rijndael for the
rest of the confidential stuff (med data actually).

The issue is that if this module is going to be set up by many different
people, there will have to be some kind of set-up administration
account. Should that account have a user name and password of its own?
If so, something in the docs will have to reveal what it is, even if it
is not in the perl source code in plaintext. So a hostile hacker would
still be able to find out the default password, if it still existed, if
such docments are available. Saving the default account as a crypt
digest is useless if the docs tell everyone what it is anyway.

Better either:

1. To allow only one use of such an account, just at initial installation

-or-

2. To not have ANY default account, but allow ther first admin login to
be without a password at all, and create a real account then

-or-

Have some kind of sysadmin, locally run script set an admin password for
the package; this would not be in cgi-bin and could not be run remotely

-or- (your suggestions here)....


--Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,983
Messages
2,570,187
Members
46,747
Latest member
jojoBizaroo

Latest Threads

Top