Sharikov Vladislav
Sharikov Vladislav

Reputation: 7269

Correct using of CGI::Session, Perl

I need to protect all pages on my site by login and password. I have one entry point, so it wouldn't be so hard. It is working now at the moment, but I want to improve authorization system (yes it works, but I want it would work correctly).

Code which check login and password is so:

my $sth = $dbh->prepare(qq{select count(*) from admin where login = '$input_login' and password = '$input_password_hash'});
$sth->execute();
($count) = $sth->fetchrow_array();
$sth->finish();
if ($count eq 1) 
{
    $session->param("user_logged_in", 'true');
    print '<META http-equiv="refresh" content="0;URL=/">';
}

2 questions about it: 1) Is it correct at all? 2) Script behaviour for end-user is so: user writing his login and password, form is sending, login page is loading again and after this (redirect to login page with blank fields and showing it for 1 second) protected data is appearing. How to remove showing login blank form and just login immediately? Inputting login and password, sending form, and data is showing immediately, not after showing blank login for 1 second. I think it is about meta redirect. What do you think?
It is first 2 question.

When a user clicks another link or re-visits the site after a short while should we be creating a new session again? Absolutely not.

Quote from documentation of CGI::Session CGI::Session Tutorial.

It says, that I should firstly check if user session is exist and if not, new session would be created. Code should be so:

$cgi = new CGI;
$sid = $cgi->cookie("CGISESSID") || undef;
$session = new CGI::Session(undef, $sid, {Directory=>'../tmp'});

But for me this code is working fine too (I can get access to session variables):

$session = new CGI::Session(undef, undef, {Directory=>'../tmp'});

3) Can you explain me why this code works? First code works too. But 2nd code (without $sid as 2nd parameter) have not to work (but it works).

Quesiton about accessing data from session:

$authorised = $session->param("user_logged_in");

4) Is it correct to access session variables this way?
5) What if I need access to $session on other script? How should I get access to $session?

Upvotes: 2

Views: 1749

Answers (1)

David-SkyMesh
David-SkyMesh

Reputation: 5171

(1)

For starters, you have an SQL Injection vulnerability:

Change this:

my $sth = $dbh->prepare(qq{
   select count(*) from admin 
   where login = '$input_login' and password = '$input_password_hash';
});
$sth->execute();

to this:

my $sth = $dbh->prepare(qq{
   select count(*) from admin 
   where login = ? and password = ?;
});
$sth->execute($input_login, $input_password_hash);

(2)

Instead of doing a client-side (META-EQUIV) redirect from HTML, do a client-side redirect (HTTP) initiated by the server.

Change:

print '<META http-equiv="refresh" content="0;URL=/">';

To:

print $cgi->header('Redirect: /');

(3)

I haven't recently used CGI::Session directly like that, but I'd guess that it's designed to call new CGI() for you in the default case.

I wouldn't do it that way; I'd call new CGI() directly. edit: example:

my $sparams = { name => 'MY_APP' };
my $cgi     = CGI::Simple->new;
my $session = CGI::Session->new(undef, $cgi, {}, $sparams);

# use $cgi for GET/POST params
# use $session for header & session storage.

print $session->header;
my $sval = $session->param('some-session-var');
my $opt1 = $cgi->param('some-get-var');

(4)

Yes, that's OK.

(5)

Then instantiate the session in those other scripts. You need to match the cookie name, path and storage method (using defaults will achieve that).

Upvotes: 2

Related Questions