Monks,

I'm responsible for the coding of a community website for a group in the North of the UK. As part of this, we need to include some "member-only" features, such as planning of events, profiles and more extensive contact information than we want to make publically accessible.

I've developed a script in CGI that will take, and validate, a username and password, storing both pieces of information in instance variables within the script (the password obviously crypted). The script can then output the site's menu dependant on whether the user is logged in or not. I should point out that the user validation and menu output is handled by the same script - the login state is not passed out to a secondary script. The menu itself is in a frame so that it doesn't get refreshed, and hence the username/password variables reset each time a content page is loaded.

When member-only content is accessed, a second script, serveContent, is called, into which is passed the username, a crypted version of the password, and the page which the user is attempting to access, which again checks user authorisation and either displays the requested page or demands the user log in.

I don't want to drop cookies to control the login for various reasons - not least because they've caused problems in the past within the group and there's a lot of opposition to them. This is fine, I don't need data persistance - when the entire page is refreshed, the instance variables containing the username and password within the login script are reset and the user is logged out.

I've set a quick version of the page running with this code and it seems to work well - logins/logouts are handled efficiently and the load-time is nice and fast, even for accessing member-only pages.

I can't help but think that this double-authentication method could cause some loadtime issues in the future, as the site and its memberbase expands. This isn't an issue at present, although it's something I'm looking into.

What I'm interested to know is whether anyone knows of any security problems that could be caused by doing things this way rather than a more "conventional" method of handling user authentication? Has anyone done something this way in the past and hit problems?

Looking to the future, do people think that this method is likely to cause problems with access times, and can anyone suggest a better way of implementing this? I'm thinking about unique session IDs, that can be generated and validated in-code, without a call to the database being required.

I should point out that I'm not after something militarily secure - but I wouldn't like phone numbers of members and stuff like that passing out into the public domain.

I'm very interested to know any thoughts/comments/criticisms people have about this way of doing things .. and any suggestions would be appreciated.

Cheers ..
-- Foxcub

Replies are listed 'Best First'.
Re: Security in CGI and User Authentication
by mirod (Canon) on Dec 03, 2002 at 13:11 UTC

    Just to cover all bases: you realize that unless you run the member-only part of the site under SSL you have no security at all? In HTTP passwords are passed in quasi-cleartext (when the user enters it the first time), so any measure you take only gives you the illusion of security.

    As for load times, it really depends on the load on your server, but I am not sure you have to worry yet. I found this mod_perl talk quite interesting, and they quote is 40/50 hits per second as a ballpark figure for when to move to mod_perl. You should be really happy if you get that kind of traffic (and your community should be worried about the cost of bandwith at that point)!

      Yep, I'm aware of the HTTP password security "problem" .. I'm running the user authentication components of the page using SSL already. Should probably have mentioned that up there somewhere :)

      Having said that, though, and just out of interest, would it not be possible to write some perlscript that crypts the password client-side, before it's shipped across to the server? Purely a "on-the-fly" question .. not something I'd even thought about until just now.

      -- Foxcub

        You may find this interesting. The site contains javascript (yes I know javascript sucks people) implementations of MD5 and other hashing functions. Yahoo uses it for non-SSL logins.

        -Lee

        "To be civilized is to deny one's nature."

        It still won't work because the password hash goes over the network in clear, so all I have to do is sniff the cookie and feed it back to you. I needn't decrypt it - I already know it's a valid password hash as long as the user doesn't change his password.

        If you want the client to actively encrypt the data using some sort variable token not sent across the network, well, that's exactly what SSL does.

        (Still, it would have been nice if HTTP natively had some sort for secure authentication like APOP's challenge-response mechanism. Alas, it doesn't (and can't - it's a stateless protocol).)

        Makeshifts last the longest.

        Perl requires a perl interpreter. Not to mention theres no easy way to hook perl into IE/MOZ/etc (to my knowledge).
Re: Security in CGI and User Authentication
by abell (Chaplain) on Dec 03, 2002 at 16:16 UTC
    When member-only content is accessed, a second script, serveContent, is called, into which is passed the username, a crypted version of the password, and the page which the user is attempting to access, which again checks user authorisation and either displays the requested page or demands the user log in.

    Please, correct me if I am not interpreting your words correctly. From what I understand, your navigation frame loads the pages by opening in the display frame an url of the form

    https://whatever/cgi-bin/something?user=me&pass=secret.

    If the tokens passed in the GET request are all you need to "authenticate" the user, then be aware that they may be stored in the history and automatic completion of the browser and may be passed as referer header to external sites accessed by the user from your pages.

    A more correct (and standard) system requires passing to the client only a randomly generated token which is associated server-side to the userid. Urls become

    https://whatever/cgi-bin/something?token=randomstuff

    and the association token<-->user on the server expires after some time from its creation or from its last invocation. This prevents information from leaking to an attacker who has access to the client after the user.

    Of course, this does not guarantee full security, but should be an improvement over your scheme.


    Cheers

    Antonio Bellezza

    The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket
      Apache::Ticket* in the Eagle Book has a very cool approach to this sort of stuff. The basic approach is to redirect http requests without a 'ticket' (param/cookie/whatever) to a auth server that performs some sort of auth on the user, creates a crypto ticket with the user's name, remote ip, timestamp, contained in it and redirects the user back to the orig server. So the client now has a ticket that can be used in every request and the original server can read and validate it using the auth servers public key. iirc.... :)
Re: Security in CGI and User Authentication
by Chady (Priest) on Dec 04, 2002 at 08:01 UTC

    it doesn't matter much here, but I once used a cookie-less login.

    I had a site to do for matching couples, the whole thing was for one event only. so I had a set of usernames/passwords (500 to be exact) and was to do the questions part as a website ( the matching had to be done on the spot at the party ).

    anyways, I didn't want to log people in and out using cookies, and security wasn't much of a big deal in this particular project, so I hashed the username+password with MD5 and put the hash in the database along with a field for the number of questions they have answered.

    on each hit, I sent the hash as a hidden field, then on submit I checked the number of questions and the hash, and knew what user is logged in. It proved to be pretty effective.


    He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

    Chady | http://chady.net/