
By
Shane Jester, Campus Web
Administrator
Do
you have a home-grown Web application that you want to limit access to,
but also want access to be secure? Using server authentication is
fine and all, but what if you want to have different users with
different functions inside the application. You could set a cookie,
based on the username provided at login, but it sure would be easy for
someone to create a false cookie to gain access to secure parts of the
application. Here is a way to avoid that problem by using mod_perl and
MD5
The concept is to take the username from the login form and process
it through a perl script. You can then add a value that is only know
by the web application, a secret-code if you will, and append it to
the username. Then encrypt the new variable and set it as cookie in
the web browser. Since it is encrypted, it can't be re-created
without knowing the secret-code, and only you can recreate the MD5
hash to verify that the cookie is authentic. Even if someone got past
the initial authentication mechanism (i.e. Apache authentication), they
can't create a cookie to spoof your system without the secret hash
phrase.
Basic perl code
This section is in the perl script that you pass your initial login
information from your login form. Hopefully you are doing this
over https or it defeats the whole point of security. Note, that I
have not included any code for authentication of the user, since there
can be so many different mechanisms (i.e. LDAP, Apache auth, etc).
This is just the code that prevents people from spoofing your
application as a different username than the one they use to login.
use Digest::MD5 qw(md5_base64);
my $uid = $query->param("uid");
###Capture username from form
my $secret = "secret_text"; ###Secret Text used to
generate cookie hash
my $data = $uid . $secret;
###Combine the username with the secret text
my $digest=md5_base64($data);
###Encrypt the data with MD5
#store values as array
my $cookie = $query->cookie(-name =>'myapplication',
-value =>"$uid:$digest",
-domain => 'yourdomain',
-path => $path,
);
print $query->header(-cookie=>$cookie); #### Create
the cookie
print $query->start_html("Login Results");
print "<meta http-equiv='REFRESH' content='1; url=http://yourserver/entry.pl'>\n";
###Redirect to the application
print "<a href=\"$url\">$text</a><br>";
print $query->end_html();
This next section should go at the top of each perl script in your
application:
use Digest::MD5 qw(md5_base64);
print header(), start_html(-title=>"Application Title");
my $userhash = cookie("myapplication");
###grab the cookie
my @user = split(/:/,$userhash); ###isolate the MD5
hash
my $uid = $user[0]; ### grab
the username from the cookie
my $secret = "secret_text";
### This must be the same as in the original section
my $data = $uid . $secret;
###Combine the 2 variables
my $digest=md5_base64($data); ###Regenerate the hash
if ($manager[1] ne $digest) {
###compare the checksum of the original hash with then newly generated
hash.
print "<b>You must login to perform this action.</b><br>";
print "<a href='http://yourserver/login.html'>Press here to
login</a>";
print end_html();
exit(1);
} else {
Do some stuff....your are in.....
}
Once they are in, you can use the username value to allow certain
users to perform different functions inside your code. This is a very
minimal security mechanism, but you can do many things to make it more
secure, such as generating a unique session ID that you store in a local
database or limit the user to a certain IP address. You can also
generate a timeframe in the cookie, so that the authentication only
lasts a certain amount of time. In the case above it lasts until the
user closes their browser.
Conclusion
As is always the case, the quality of the security is often related
not only to your knowledge, but also the time you invest into the
application. I hope this gives you a starting point and better
understanding of how to begin making your applications more secure. |