Perl created page using old data (IE)


I have an HTML page with a form with 2 elements, name and password.  When submitted, the form calls a perl script that validates the username and password against a file, updates a file called "currentser" and redirects them to the next page.  This works fine.

On the next page, the current user details are retrieved by the next script and the web page is built using users full name, date, access level etc which have just been retrieved.

My problem.

I have two test users, fred and john.  If I log on as john with the correct username/password combination on the first run, the screen builds correctly and knows that I am user john.

If I then close the browser, log in as fred with the correct username/password combination the page is built with john's details again.  If I click "refresh" it re-loads with fred's details. A bit of a security hole methinks.

If I get the username/password combination wrong at any point, I am re-directed to the "access denied" page, which works correctly.

I am using IE6 version 6.0.2600.0000co

I have enabled "Empty Temporary Internet Files When Browser Is Closed", I have disabled "Userdata Persistence", I have set history files to 0 days and also set the "Check or New Versions Of Pages" to be "Every Visit To The Page" and it still won't pick up the right data without a refresh.

Where else could it possibly be storing the information?

Any ideas, please?

Thanks in advance.

Who is Participating?
GorGor1Connect With a Mentor Commented:
Problems I see:

Without seeing your code, I already see a potential problem you're going to have.  When using the 'currentuser' file for data storage, if user1 and user2 try to login simultaneously, there's no telling which user is going to be stored in that file.  Also, if a script is using the 'currentuser' file to calculate permissions and user2 logs in during that time, then the 'currentuser' file will contain data that is invalid for user1.  Also, if 'mainscreen.cgi' doesn't access the 'currentuser' file IMMEDIATELY upon the posing of the login script (i.e.  'mainscreen.cgi' waits for a user action before accessing the 'currentuser' file) and user2 tries to login, the information in the 'currentuser' file will be invalid for user1.

Fixes (patch fixes):

Using Perl code, you can 'lock' the 'currentuser' file until 'mainscreen.cgi' is done using it.  But you will still have one problem.  If user1 doesn't log out correctly (i.e. doesn't click 'logout' on your page) then the 'currentuser' file will not be handled the way you have intended.

Recommended changes:

Instead of using a 'currentuser' file for data storage, the better way (in my opinion) to do the permissions is by creating a non-persistent cookie that contains the username.  (NOTE: Create the cookie using Perl NOT Javascript whenever possible!).  Then have 'mainscreen.cgi' read the cookie and the cookie's value.  That way 'mainscreen.cgi' will know who is accessing the page and the script can generate the menu items, etc. (that you have defined) for each user on the fly.  Plus you don't have to worry about timing issues like you would when using a 'currentuser' file.  A non-persistent cookie (non-persisent is created by not giving the cookie an 'expires' parameter) will then expire when the user closes his browser window and he won't have to click a 'logout' button or link.

Putting it all in one script:

This is fairly simple to do.  Introduce a new variable to your script called $page.  This will let your script know which page your user is expecting the script to generate.  The main program would look like this:

my $page;

#Main program
if($page eq "0" || $page eq "")
    #Display Login page
    #Call subroutines from here to keep "Main" looking clean
elsif($page eq "1")
    #Display Main Screen Page
elsif($page eq "2")
    #Next page (if applicable)
    #Program should never get here so...


When calling the script from a form, you would have to include a hidden field containing name="page" value="x" where "x" is the page you want to generate.

Another note:  When using this type of program flow, you will still need to pass all your required values from one page to the next since Perl does not store the values anywhere.  Each page is treated as its own entity.  So even in the perl script that generates the html pages, you will have to include hidden form fields on each page to pass the variables back to the script on submit.  If it's a simple text link and not a form, just include the parameters in the URL.

Let me know if you need more help with actual code.  I'm at work right now, so all my code that I could copy-paste into here is not accessible and I don't want to make any errors that will throw you for a loop.
Are you using cookies on your second page?
NTIVERAuthor Commented:
Nope - I am not using cookies anywhere on my pages.  The only place data gets written is to text files on the server, no client side data is stored.

Also, I have put this in the script as it builds the webpage to try and stop it caching:

<META HTTP-EQUIV="Expires" CONTENT="Fri, 12 Jun 1981 00:00:01 GMT">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">

Makes no diference though :(

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Are you deleting this currentuser temp file after the second page loads or are you leaving the temp file intact?  I think this may be where your problem lies.  Could you go into more detail on the flow of your perl script(s) and what they're actually doing?  Do you really need this temp file?  Why not just pass the information to the next cgi script with hidden form fields?  Please clarify and I'll/we'll try to help you track down the bug.
Another option is to use one cgi/perl script to perform all functions and setup more of a state machine-type flow in your script.  This way you shouldn't have to use temp files.
NTIVERAuthor Commented:
OK, the user enters the first page (index.htm) and enters username and password from fields in a form.  The action on the form is a cgi script.  This script reads the username and password fields from the form, reads the users file (users.cgi) and compares the two values against each other.

If the two match, the current user (first name) is written to the current user file (currentuser.cgi).  The page is the re-directed to the main application screen (unless the username/password don't match, then you are redirected to the access denied page (accessdenied.htm).

Once at the main application screen (mainscreen.cgi) a new script reads the current user from the current user file,  then reads the user access file (useraccess.cgi) using the current user as the key - the contents of this file determin what the user has access to (menu's etc although these aren't set up yet).

My idea, was to make sure that people entered the main application screen via the username/password fields, and could not just go straight to the page.  I intend to clear out the current user file when a user clicks "logout" but I haven't done this part yet.

Additional info:

Once the second user has logged on (prior to clicking refresh), if I check the files on the system, they have all been updated correctly.  The current user file has the second user in it, so I know that these are working at the correct time, it's purely a browser refresh matter I think.

I have tested this on a colleague's Win XP machine, and his seems to update correctly without the refresh (although typical me, I can't remember what version of IE he has!).

Gor: Could you please explain more about the "state machine-type flow" you mention?

Also, if any body has other ideas either about why this may be happening or a better way of doing things, please let me know - I am relatively new to Perl still.

Thanks :)


I screwed up with my sample Main program code.  $page should not be initialized using 'my $page;'.  It should be initialized just like the rest of your parameters collected from the form:

my $page = param('page');

and in the form:

<input type="hidden" name="page" value = "x">
NTIVERAuthor Commented:

I have found where the problem lied.  The redirection I was using was as follows:

The Perl script did the authentication against the username and password, then using "print" I built a small web page encompassing a javascript script that did a "window.location.replace()" statement to actually re-direct the browser depending on whether you authenticated or not.

I have found that by replacing this method with:

print "Location: xxx.cgi";

It works fine (why I bothered with JS I have no idea :)

So, although your suggestion wasn't the answer to my problem, I am going to change the way in which my whole application works, so that I use non-persistent cookies as you mention as I think this will be infinitely better.

Thank you to all the EE experts for your help and sugestions.


No problem...glad I could help!
NTIVERAuthor Commented:
One other question, and I'll post it as a 'proper question' if you like, have you an example of the simplest, easiest, most straight forward script to create a cookie using perl?  I've downloaded about 5 examples from the web and they all see to have too much 'user-configurable' stuff in them.  I just want an example that writes one simple line away so that I can prove it works, then I can play with it later.

Can you help?


Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.