Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

How to make a secure website

by cranberry13 (Beadle)
on Jul 07, 2004 at 08:28 UTC ( #372314=perlquestion: print w/ replies, xml ) Need Help??
cranberry13 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,
I am creating a website that will require the user to use a login and password.

I've looked at websites that explain how to make a site secure and many of them recommend not putting the username of the user as a cookie.

I would never save the password in a cookie and I would never pass the username or password as a hidden variable (that's just dumb) .... my question is this:

The sites that suggest not putting the username or userid as a cookie -- how else am I supposed to figure out whether a user is logged in or not? Is there any other way?

Right now I have it so that when a person logs in (or if they create a new account) I place a cookie saying that 'this userid is logged in'. Every time they click on a link (ie. go to their account manager, post an event, etc.) I immeidately check the cookie to see who it is and if there is not userid cookie then I print the login page and tell them to login.

Anything insecure about this? If so, please let me know and tell me how to make a site 100% secure with regards to logging in and passwords (currently the passwords are stored in a DB and encrypted).

Also, people have recommended storing the sessionid in the DB along with the user id so I can figure out who the user is .... Correct me if I'm wrong but that means anytime they view another page they my programs will have to query the DB -- isn't that inefficient? Thanks!

Comment on How to make a secure website
Re: How to make a secure website
by neeraj (Scribe) on Jul 07, 2004 at 08:36 UTC
    Try out CGI::Session and in that generate session ids using Digest::MD5.
    I haven't tried it but i guess its foolproof.
Re: How to make a secure website
by knoebi (Friar) on Jul 07, 2004 at 08:37 UTC
    Usually you use CGI::Session or similar and save the SessionID in the cookie.
    There is no way to make a website 100% secure. I'am thing you allready use strict; use warnings;. For websites (or any other Application with userinput) I suggest you use taint-checking on user input and actually CHECK the input (eg Data::FormValidator).
    Take care quoting everything which could escape a value in any layer (perl, DB (sql inquetion, DBI does this for you if you use placeholders), ...).
    And of course use actual versions of httpd, perl and modules.

    ciao

    knoebi
Re: How to make a secure website
by Enlil (Parson) on Jul 07, 2004 at 08:41 UTC
    The sites that suggest not putting the username or userid as a cookie -- how else am I supposed to figure out whether a user is logged in or not? Is there any other way?

    Well one way is to use sessions. A good way to find out about them and how they work is the CGI::Session::Tutorial.

    -enlil

Re: How to make a secure website
by EvdB (Deacon) on Jul 07, 2004 at 09:53 UTC
    I recently asked a similar question and the answers there are very good.

    In summary you want to put something meaningless but unique into the cookie (ie a long random number). This is then used to look up the session related data in the database:

    my $cookie = $cgi->cookie('session_token'); # $cookie is '9874354683216735468453121845168441'; if ( $cookie && $cookie =~ m/some match/ ) { my ($session_id) = $dbh->selectrow_array ("select id from sessions where token = ?", undef, $cookie ); }
    It is the actual presence of the cookie that is used as an indicator that the user is logged in, as well as getting a session_id from the database. All this said the only real way to secure the website is to run it over https as otherwise cookies can be intercepted and used in replay attacks.

    --tidiness is the memory loss of environmental mnemonics

Re: How to make a secure website
by kiat (Vicar) on Jul 07, 2004 at 12:51 UTC
    Hi cranberry13,

    Every time they click on a link (ie. go to their account manager, post an event, etc.) I immeidately check the cookie to see who it is and if there is not userid cookie then I print the login page and tell them to login.
    Cookie values can be changed or hijacked so it's not entirely safe to depend on them without taking some precautions. For example, if you set a user with a cookie value of 'abcde' and if I'm able to get to that value, I could masquerade as that user by tweaking the cookie file in my computer. That's what I think but I may be wrong.

    I use MD5 to set a unique cookie value and that value is saved into the db. The user is recognised by the cookie value. Every time he or she logs in, a new cookie value is created and set. This new value replaces the old one in the db.

    I'm not 100% sure if my method is secure but I think it's better than relying on one unchanging unique cookie value.

Re: How to make a secure website
by bibo (Pilgrim) on Jul 07, 2004 at 14:09 UTC
    You are interested in using "cookies" and "user authentication". Both of these are rich and complex topics. I suggest you use those as keywords to Super Search here on PM, or on google, and also check out some of merlyn's writings, such as Basic Cookie Management to help you get some background information and techniques.

    There are quick answers to your questions, but getting a good grip on the big picture is priceless.

    --bibo

Re: How to make a secure website
by danielcid (Scribe) on Jul 07, 2004 at 17:49 UTC
    You can write a "random" string to the cookie, and create in the database a table that links this "random" value to the user ID. You can also "lock" this random value to a specific IP address, user agent ,etc :) []'s
Re: How to make a secure website
by bunnyman (Hermit) on Jul 07, 2004 at 21:02 UTC
    Anything insecure about this?

    What is stopping anybody from giving themselves a cookie that says userid="admin" ? They would not even need to know the password for admin to do it.

Re: How to make a secure website
by Your Mother (Canon) on Jul 07, 2004 at 21:21 UTC

    You should also, if possible, do the login page under https. That way the password and user are never sent unencrypted; mailing passwords is also not the best idea (though a very user friendly one) so you might make passwords that have been mailed temporary, user must update on the site. Can also make sure users enter "real" passwords (minimum of 8 chars; and for the serious security run it against cracking code/dictionary to improve its unguessability -- alternatively, you could lock users out who guess wrong 10 times). Anyway, the links bibo gave are a good place to start. A truly secure site has a lot of angles.

Re: How to make a secure website
by Jeppe (Monk) on Jul 08, 2004 at 12:24 UTC
    You should take a look at Apache::Session. It might be what you're looking for.

    Seriously, store only a session id in the cookie. Don't store a cleartext user id, and make sure you somehow make it impossible to calculate a valid session id. That is, the session id must be a large number - too large to be brute-forced. The distribution of the algorithm that produces the session id must be flat.

    And - of course - make sure the login is performed over an https connection.

    Other than that, make sure you properly process anything the users submit through forms or url tampering..

Re: How to make a secure website
by Anonymous Monk on Jul 09, 2004 at 16:03 UTC
    A good session-id would be constructed like this:

    choose a few (around 70) strings at random

    place username,IP,user-agent among them

    calculate the Digest::MD5 from their concatenation

    prepend this and the (entered) password to each of them

    sort these (combined) strings by their Digest::MD5

    concatenate the original strings in this sorted order

    calculate the Digest::MD5 of this concatenation and use it as session-id

    place the original strings at key session-id into the database

Re: How to make a secure website
by redhotpenguin (Deacon) on Jul 09, 2004 at 16:12 UTC
    Have you looked at Apache::AuthCookie? It takes care of authentication and authorization for you. You create a session key which is passed as the value of the cookie sent to the user, once the user has been authenticated. This key links to a server side copy of the key which is associated with the user's name. Every request a new cookie is created. This is called 'ticket based authentication' and is generally accepted as a best practice for authentication and cookie handling.

    No critical information is kept in the cookie itself - just a link to a server side file which contains the username, remote IP, hostname, and whatever else you need to determine the user is actually who they say they are.

    Usage is relatively simple, you need to subclass 2 methods and configure access in httpd.conf:

    in your httpd.conf
    <Location /protected>
    AuthType My::Apache::AuthCookieHandler
    AuthName MyProtectedArea
    PerlAuthenHandler My::Apache::AuthCookieHandler->authenticate
    PerlAuthzHandler My::Apache::AuthCookieHandler->authorize
    require valid-user
    PerlHandler My::Apache::PerlHandler
    </Location>

    in My::Apache::AuthCookieHandler

    sub authen_cred ($$\@) { # Authenticates the user and returns a key
    my $self = shift;
    my $r = shift;
    my @cred = @_;

    my $user = My::User->new;
    return unless $user->auth(@cred);

    my $session_key = My::MD5->new(My::RandomData); # session_key is something like 'lkj125825yk523'
    _save_to_disk({$session_key => $user});
    return $session_key;
    }

    sub authen_ses_key ($$$) { # See if there is a user associated with this key
    my ($self, $r, $session_key) = @_;
    my $username = _get_from_disk($session_key);
    $username->valid ? return $username : return;
    }
Re: How to make a secure website
by Anonymous Monk on Apr 30, 2008 at 08:20 UTC
    As some of the others pointed out, there's a lot to be considered when securing a website login form. Some other things to consider are:
    • If the login is wrong, don't let on whether it was the username or password that was wrong.
    • If you print out the username (e.g. you print 'there is no user Bob registered here') make sure you html encode the username first to prevent cross-site scripting attacks.
    • The choice of session id hashing algorithm is important. MD5, the default in many cases is not really suitable for applications which require a good level of security.
    • Make sure any database lookups you do carry out are protected against SQL injections.
    And there's plenty more. You can get a bit of an introduction to website security at my site WebsiteSecurityBook.com. (it's all free). I'm gathering up information on all the different security issues to be considered when securing websites.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://372314]
Approved by Corion
Front-paged by calin
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (8)
As of 2014-12-25 01:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (159 votes), past polls