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

I bought this script custom-made in 2001 so a lot of the code seems a bit different than what I've been using. In short, after years of this script not being around I decided to see if it still works.

It doesn't.. And I was wondering if someone could help me figure out what the problem might be. It MIGHT have something to do with the MySQL commands because I have NO experience with MySQL and the rest of the code looks okay to me.

The script does load the form when the page loads, but regardless of the username and password you input (even blank), it gives an internal server error 500 page. Even when I try to print errors to the screen, it just spits a 500 page at me.

The error occurs after submitting the form. Any ideas what might be wrong?

#!/usr/bin/perl use CGI::Carp qw(fatalsToBrowser); use CGI qw(:all); use CGI::Cookie; use DBI; use Digest::MD5 qw(md5_hex); require("../functions.cgi"); require("../config.cgi"); %cookies = fetch CGI::Cookie; if (defined($cookies{'user_id'})) { print "Content-type: text/html\n\n"; print "You are already logged in."; print "<script>window.location = 'index.cgi';</script>\n"; exit; } if (!($ENV{'REQUEST_METHOD'} eq "POST")) { { print "Content-type: text/html\n\n"; print qq~ <table border='1'> <form method="post" action=""> <tr> <td> <b>Username:</b> </td> <td> <input type='text' length='30' name='form_user'> </td> </tr> <tr> <td> <b>Password:</b> </td> <td> <input type='password' length='30' name='form_pass'> </td> </tr> <tr> <td colspan='2'> <input type='submit'> </td> </tr> </form> </table> ~; } } else { $username = (param('form_user')); $userpass = (param('form_pass')); $userpass = md5_hex($userpass); #check the database my $dbh = DBI->connect("DBI:mysql:$edt_dbase", $mysql_user, $m +ysql_pass) or print DBI->errstr; my $sth = $dbh->prepare("SELECT * FROM $users_table WHERE user +name = '$username' AND user_password = '$userpass'"); $sth->execute; if ($sth->rows < 1) { print "Content-type: text/html\n\n"; print "Login information incorrect."; $dbh->disconnect; print "<script>window.location = 'login.cgi';</script>\n"; exit; } else { while ($data = $sth->fetchrow_hashref) { $u_id = $$data{"user_id"}; my $auth_user = new CGI::Cookie(-name => + 'user_id', -value => + $u_id); my $auth_pass = new CGI::Cookie(-name => + 'user_pass', -value => + $userpass); #$cookieset = $auth_user . ";" . $auth_pass; print "Set-Cookie: $auth_user\n"; print "Set-Cookie: $auth_pass\n"; print "Content-type: text/html\n\n"; print "Welcome " . $username . ", you have successfull +y logged in.\n"; print "<script>window.location = 'index.cgi';</script> +\n"; } } $dbh->disconnect; } } print "(..)";

Edited by davido: Added readmore tags.

Replies are listed 'Best First'.
Re: Debugging a login script using MySQL
by Thilosophy (Curate) on Jan 05, 2005 at 04:59 UTC
    I do not know why your script dies, but are you sure you really want to use it? It seems very insecure.
    • It makes cookies with the user's password, which as a result will be sent around all the time. (Actually, the MD5 of a password, which is better, but still not good)
    • It is vulnerable to SQL injection attacks:
      my $sth = $dbh->prepare("SELECT * FROM $users_table WHERE username = ' +$username' AND user_password = '$userpass'"); $sth->execute;
      A user called ' or 1=1 -- could probably login without a password. That should really be:
      my $sth = $dbh->prepare("SELECT * FROM $users_table WHERE username = ? + AND user_password = ?"); $sth->execute($username, $userpass);
    • It looks like any user with a cookie "user_id" is assumed to be logged in. It is easy for users to make such a cookie by themselves.
Re: Debugging a login script using MySQL
by Anonymous Monk on Jan 05, 2005 at 01:22 UTC
    Check your webservers error logs. This and more tips in CGI Help Guide
      I can't find them, to tell you the truth. I'm on a new webhost I haven't been with before and I'm just getting used to Cpanel XP.

      I did make progress by modifing to the code below. It doesn't kill the script now (who knows why) but it doesn't sign in either. By adding the print header line the 500 error is gone but it doesn't say the login was successfull or the login failed. So I'm thinking it has something to do with the database lines.

      Anyone have any ideas?

      else { print "Content-type: text/html\n\n"; use CGI::Carp qw(fatalsToBrowser); print "test<br><br>"; #exit; $username = (param('form_user')); $userpass = (param('form_pass')); $userpass = md5_hex($userpass); #check the database my $dbh = DBI->connect("DBI:mysql:$edt_dbase", $mysql_user, $m +ysql_pass) or print DBI->errstr; my $sth = $dbh->prepare("SELECT * FROM $users_table WHERE user +name = '$username' AND user_password = '$userpass'"); $sth->execute; print "test 2"; if ($sth->rows < 1) { print "Content-type: text/html\n\n"; print "Login information incorrect."; $dbh->disconnect; print "<script>window.location = 'login.cgi';</script>\n"; exit; }
        By adding the print header line the 500 error is gone but it doesn't say the login was successfull or the login failed.

        So, what does it say now? Just "test" or also "test 2". If something is wrong with the DB, there should be no "test 2". The use CGI::Carp qw(fatalsToBrowser); should print any error messages to your browser. Does it?