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

I am writing a login page for my web application, and i want to implement error messages for when incorrect login details are submitted. I have so far created code which will give an error if an incorrect password is entered, when an incorrect username is entered, or when the username and password fields are left empty, my problem is giving an error message when an incorrect username and password combination are entered. I have tried everything i can think of, but keep getting an "internal server error". The code i am using is shown below
} # Display error if username or password fields are left blank if($user_name eq "" || $password eq "") { &error(); } else { #check if the user name and password are in the database $sth = $db->prepare(q{SELECT user_id, password from user where user_id + = ?}) $sth->execute($user_name) while(@row = $sth->fetchrow_array){ if($user_name eq $row[0] && $password eq $row[1]) { #go to main page } else { # If the username or password are not in the database + if($user_name n +e $row[0] || $password ne $row[1]) + { &error(); }
Can anybody see why this code isn't working? I would greatly appreciate any help you can give. Thanks

Replies are listed 'Best First'.
Re: login page
by graff (Chancellor) on Dec 19, 2006 at 02:42 UTC
    Please reconsider your strategy and assumed specs. You are supposed to be protecting valid user accounts from unauthorized access. If unauthorized hackers happen to guess a valid user name, but fail to guess the correct password, you should not encourage further attempts by telling them, in effect, "OK, you got a usable username, now you just need to get the password."

    (Surely you wouldn't consider saying something like "the password was not 6 characters as expected and had the wrong character in the third and fifth positions..." -- the more information you provide, the more you jeopardize your own security.)

    If either the user name or password is incorrect, you should just be responding with "Invalid login attempt, please try again." Don't say anything more about what, in particular, was invalid. If either or both fields are empty, you can say "You need to fill in both user name and password." That's it.

    So you really have only two distinct responses to worry about, and the different conditions to trigger one vs. the other should be pretty simple to work out.

      Along the same lines, it's a bit of a security risk to store cleartext passwords in the database. Better to store a hash or encrypted version of the password. Check out the MD5 and Crypt:: family of modules on CPAN. You might also want to consider letting the database do the matching work with something along the lines of:
      my $user_info = $dbh->selectrow_hashref(q/
         select <some fields> 
         from users 
         where id = ? and password = ?
      /,undef, $id, $password);
      
      if (defined $user_info) {
         # valid user
      } else {
         # handle a bad one here
      }
      
Re: login page
by GrandFather (Saint) on Dec 19, 2006 at 02:21 UTC

    I suggest for a start that you add use strict; use warnings; to your code. Most likely a copy and paste error, but there is a missing semicolon after the prepare statement and the following statement. Are you sure both row entries are not null?


    DWIM is Perl's answer to Gödel
      Thanks for the feedback. Yes that was a copy and paste error, sorry. I am using
      use strict; use warnings;
      The error() message does not seem to be the problem as it is printing out the correct result in the other if statements in the code i posted. Yes both entries in row should be null when an incorrect username or password are entered. I expected the line
      if($user_name ne $row[0] || $password ne $row[1]) { &error(); } }
      to pick that up. Is this wrong?

        My database fu is not strong, but I'd expect the code to drop out of the while loop if there was not a username match - none of the code in the body of the loop would execute in that case and there would be no error handling for a non-matching user name.


        DWIM is Perl's answer to Gödel
Re: login page
by jettero (Monsignor) on Dec 19, 2006 at 02:13 UTC
    If there isn't a usefull error in your webserver log then the problem is probably not printing your document header (use CGI; my $cgi = new CGI; print $cgi->header;) before printing the error result...

    That's just a guess. I'm not sure the relevent code is show.

    -Paul

Re: login page
by stonecolddevin (Parson) on Dec 19, 2006 at 02:56 UTC

    You might want to check out Authen::Users. haven't personally used it, but I'm a fan of the Authen family.

    meh.