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

Hi Monks! I'm trying to make a simple authentication script which would render (or not) some html pages depending on whethet user is logged. I use CGI::Session mechanism for this, please see the code: This is index.pl:
#I've not posted use directives, HTML::Template variables declarations + and et ceterea, because it doesn't actually matter in this case. if (!$cookie{CGISESSID}{value}[0]) { #checkif there is a session cooki +e in user's browser. print "Content-Type: text/html\n\n"; print $auth->output; # render form which would require enter login + and password. } else { # render secret page
and here is auth.pl:
#!/usr/bin/perl use CGI; use HTML::Template; use CGI::Cookie; use strict; use CGI::Session; use lib ('../'); use MySite; my $q = new CGI; my %params = MySite::get_params($q); my $login = "vu"; my $password = "Stella744"; my $t = HTML::Template->new(filename => '../templates/auth_success.tmp +l'); my $t_err = HTML::Template->new(filename => '../templates/Auth_error.t +mpl'); if ($ENV{REQUEST_METHOD} ne 'POST') { print "Content-type: text/html\n\n"; print "Sorry. Don't do this."; } else { if (($params{login} eq $login) and ($params{password} eq $pass +word)) { my $session = CGI::Session->new() or die CGI::Session->err +str; my $cookie = $q->cookie( -name => $session->name, -value = +> $session->id ); #print "Set-Cookie: $cookie\n"; print $session->header(-charset => 'utf-8'); print "Content-type: text/html\n\n", $t->output; } else { print "Content-type: text/html\n\n", $t_err->output; } }
It actually works, but one issue is worrying me: the cookie named CGISESSID (which is session cookie) is checked just for is's existence, so theoretically one can open cookie file and write some random symbols to the CGISESSID's value - and script will actually render secret page! How to avoid this situation?

Replies are listed 'Best First'.
Re: CGI::Session and simple authentication
by thomas895 (Deacon) on Jun 03, 2014 at 04:50 UTC

    That's because you're not checking for anything in the session. Use $session->param like you would for the CGI object.

    For example:

    $session->param( -name => "can_access", -value => 1 ); #sometime later, likely in a different request... if($session->param("can_access")) { #show secret page } else { #not allowed to see secret page }
    ~Thomas~ 
    "Excuse me for butting in, but I'm interrupt-driven..."
      Thank you a lot, now I get it!
Re: CGI::Session and simple authentication
by taint (Chaplain) on Jun 03, 2014 at 06:17 UTC

    You can also do nifty things, like create a hash with the current time, combined with their IP address. This helps in session tracking, and helps prevent hijacking of those sessions. The current time portion of the hash can also be used nullify a session after a chosen timeout period you can set, or allow the user to set, via preferences.

    --Chris

    ¡λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH

      Thanks! But I think IP check is not a good option: most of the internet providers are using shared IPs over NAT, so until we are not switched to IPv6, when everyone will have their own real IP, IP check is almost useless.

        Most of the Internet, does have a unique IP address. Indeed many are also NAT'd. But they too can be tracked uniquely. In the case of tracking IP's to your web site; the chances of your getting two people sharing an IP, are pretty slim. In fact, there are many ways, and Perl modules to get a visitors actual origin. But perhaps more involved, than you're willing to go for something like this.

        Best wishes.

        --Chris

        ¡λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH