Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Problem with Remote User Env Variable Keeps Changing Value...

by JaredHess (Acolyte)
on Aug 04, 2006 at 20:00 UTC ( [id://565738] : perlquestion . print w/replies, xml ) Need Help??

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

The young monk approached, his orange robes whispering slightly as he moved. He bowed low and politely, steepled hands together.

When bade to rise, he finally spoke. "Wise Ones! I come seeking the wisdom of all. I would ask a boon of thee!"

"Ask! And if thy heart is worthy, it shall be given!"

*grin* Always a pleasure to parley with the other monks! Anyway, I'm running into a strange environment variable problem where the remote user value keeps changing when I refresh my browser. Strange to this perpetual Perl 'noob'!

Here's some information. I have my own module I created to house some of my frequently used variables and routines, called mymod.pm. Among these is the ability to detect the user once they log into the protected area of my web app and to track what privileges he or she has.

Here's a portion of mymod.pm:

#!/usr/local/bin/perl # mymod.pm package mymod; use CGI qw(:all); use DBI; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); @EXPORT_OK = qw(dbconnect dienice isadmin getprivilege $cwd $remoteuse +r $servername); # Database include script print header; # Get current working directory $servername = $ENV{'SERVER_NAME'}; $scriptname = $ENV{'SCRIPT_FILENAME'}; @a = split/\//,$scriptname; pop(@a); # removes the name of the file at the end. $cwd = join '/',@a; $cwd = $cwd . '/'; ####################### if ($servername eq "localhost"){ # Define remote user if working locally $remoteuser = 'me'; $file = 'E:/WAIWeb/mysql_login.txt'; } elsif ($servername eq "www.wilcoxassoc.com"){ # Define remote user when on production server $remoteuser = $ENV{'REMOTE_USER'}; $file = '/var/www/mysql_login.txt'; } else { foreach $key (sort(keys %ENV)){ print ("<p>$key = $ENV{$key}"); } &dienice("Could not connect to unknown servername of: $ser +vername"); }

In my normal script, I do a call to a subroutine inside mymod.pm called isadmin. It basically checks to see if the user has certain admin privileges for my web application.

sub isadmin { # This can takes zero or one parameter. # if param is "blocked" or no param, then # it will exit the script via dienice # If param is "check" it will continue running and return # the admin field for that record. my($param)=@_; $dbh=dbconnect(); # print "<p>Remoteuser: $remoteuser"; ## Grab user info from the table $sth = $dbh->prepare("SELECT * FROM registered WHERE username = ?" +) or dienice ("Couldn't prepare select statement: $!" . $dbh->errs +tr); $sth->execute ($remoteuser) or dienice ("Couldn't execute prepared + statement $!" . $dbh->errstr); while ($h = $sth->fetchrow_hashref){ %item = %{$h}; $user = $item{username}; # Get their username $name = $item{name}; # Get their name $email = $item{email}; # Get their email $isadmin = $item{admin}; # Get the admin column } if (length($name)<=0) { dienice("There is no username that matches $remoteuser in the database. Use a different username."); } if ($isadmin ne "Y" and $isadmin ne "S") { if ($param ne "check"){ dienice("$name, you do not have priveleges to perform this operation. Your current privilege code is: $isadmin (param is: $param)"); } } return $isadmin; }

The problem I'm running into is that something screwy happens to the returned $remoteuser variable when testing my web app on our production server. I'm having a hard time explaining it, but it sometimes mysteriously switches to a different user after multiple refreshes of the browser. Here's a snippet of the start of my actual Perl script where I pull in the $isadmin variable for the remote user. I've added in some testing statements so I can see what privilege code and isadmin state the remote user has:

#!/usr/local/bin/perl use CGI qw(:all); use DBI; print header; use lib '/var/www/wilcoxassoc.com/perl/'; use lib 'E:/WAIWeb/Perl/'; use mymod qw(dbconnect dienice isadmin $cwd $remoteuser getprivilege $ +servername); $query = new CGI; #== Some Variables ==# $title = "Internal Training Area"; $page = "View Sessions"; $viewby = param('viewby'); #Check that remote user is admin or can read the sales repository (cod +e 2). $isadmin = isadmin("check"); $privilege = getprivilege(); if (!$isadmin){ dienice("Admin code for remote user to access this page was found +."); } if ($isadmin ne "Y" and $isadmin ne "S" and $privilege ne "2" and $pri +vilege ne "1" ){ dienice("You do not have privileges to access this page."); } else { $dbh=dbconnect(); if ($isadmin ne "Y" and $isadmin ne "S"){ #display normal user template template_header_user(); } else { #display admin template template_header_admin(); } print p,"Testing...Remote User is $remoteuser"; # Returned from mymod. +pm print p,"Testing...Privilege is $privilege"; # Returned from mymod. +pm print p,"Testing...isadmin is $isadmin"; # Returned from mymod. +pm print p,"Testing...servername is $servername"; # Returned from mymod.p +m print "<a name='contents'></a>"; print "<p class=\"bodytext\">Welcome to the View Training Sessions pag +e. This page details internal training sessions scheduled for Hexagon + Metrology personnel. Click on the links below to get more information about +a particular training event. </p> <center><p class='barsmall'><a href='training_view_sessions.pl?vie +wby=descending'>View by Descending Date</a> | <a href='training_view_ +sessions.pl?viewby=ascending'>View by Ascending Date</a></bar></cente +r> "; display_contents(); print "</body></html>"; exit; }

And here's a link to an online demo of the problem I'm seeing so you can visually see for yourself what's happening.

I'm not sure what the deal is but I don't think hitting refresh should change the remote user! But it's probably some newbie error of my own. But after countless hours trying to figure this out on my own, I have decided to ask the experts. A await with gratitude any wisdom you can impart!

Replies are listed 'Best First'.
Re: Problem with Remote User Env Variable Keeps Changing Value...
by Tanktalus (Canon) on Aug 04, 2006 at 23:37 UTC

    Not that this is your problem, but this kinda stood out to me as a potential other problem you may encounter in the future:

    if ($servername eq "localhost"){ # Define remote user if working locally $remoteuser = 'me'; $file = 'E:/WAIWeb/mysql_login.txt'; } elsif ($servername eq "www.wilcoxassoc.com"){ # Define remote user when on production server $remoteuser = $ENV{'REMOTE_USER'}; $file = '/var/www/mysql_login.txt'; } else { foreach $key (sort(keys %ENV)){ print ("<p>$key = $ENV{$key}"); } &dienice("Could not connect to unknown servername of: $ser +vername"); }
    Ignoring, for the moment, the complete lack of consistant indentation (whitespace is important, folks! Just not to perl itself...), what would happen, for example, if someone set "localhost" in their hosts.conf file (or equivalent) to be your IP address? They'd get in with your privileges! While I have to admit, this is unlikely for most people to accidentally do, some enterprising hacker may figure it out, and suddenly have debug access to your entire setup.

    Instead, you're better off putting this in a machine-specific config file - so that it becomes impossible for a hacker to become you short of compromising the box itself. Securing ssh, ftp, etc., is probably much easier than securing your application against this, so I'd highly suggest rethinking how you get into your "me" mode.

Re: Problem with Remote User Env Variable Keeps Changing Value...
by imp (Priest) on Aug 04, 2006 at 21:09 UTC
    Are you using mod_perl and Apache::Registry in the production environment? If so, you might have a problem with accidental closures.

    It would also be a good idea to always use strict and warnings. That will help you identify many problems

Re: Problem with Remote User Env Variable Keeps Changing Value...
by InfiniteLoop (Hermit) on Aug 04, 2006 at 21:18 UTC