Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
There's actually a third way that nobody has discussed yet, and in fact, it's the only way to do sessions properly, and in a secure fashion without depositing any insecure information that can be misused on the user's computer: Hidden Fields.

Before you jump on and flame me, here's why: Hidden Fields do not leave "droppings" on the user's computer in any location (well ok, in their browser cache, but it expires once the page is reached anyway, if built properly). It also does not leave any bits in the URI for someone parsing their referer logs to go back into. I've actually managed to parse my own weblogs, caught an ugly referer, followed it back, and was into someone else's online mailbox. Not cool.

Putting the session_id into the URI may fail in a lot of situations, such as with users behind a caching proxy. In many countries this mode of operation is essential due to saturation of international network connections.

In my case, my users are very specific about what they will and will not allow on their systems.

  1. No cookies, at all, of any type
  2. No hashing or unique session identifiers in the URI
  3. Nothing left on their system when they leave my site

It tends to be more of a pain than the other methods, but I gain more happy users (most of them are in Europe, which tends to take a very suspiscious tack with US websites and methods lately), and I get the benefit of their input on things like reporting bugs in the bugtracker, using the cvs, and so on.

A couple of basic rules apply to any session management you build:

  1. No client information at all can be sent in the session. You'd be surprised at how many sites that do session management put client information into the session or cookies themselves, like IP or hostname. Don't.
  2. Always hash the information you pass to the client, and make sure to use good entropy when you do. There are a few sites onthe web that can check entropy of cookies for you for strength. Use them to test your cookies, sessions, and code before you go live with your site.
  3. Never assume the capabilities of the client, including their browser, proxy, cache, or connection. Each of these is subject to fail or perform in unpredictable ways at any time. Do not guess.
  4. Consider what you're passing in the session, and why, then consider it again. Is it really needed? Can you pass something else in a different way, and achieve the same result?

Now the catch, Hidden Fields have their own set of flaws:

  1. Hidden form fields aren't really hidden. Any information stored in a hidden form field can be seen by anyone who views the source code of the web page. If you've stored runtime options to your CGI script, private user data, or anything else in hidden form fields that you don't want seen (or modified) by users, then you shouldn't use hidden form fields, or take some steps to obscure that information
  2. Hidden form fields allow users to gain unauthorized access to application functionality.
  3. Hidden form fields allow users to attack CGI programs using bad input
  4. Hidden form fields make it easier for users to break your state preservation mechanism. If you are using hidden fields to track state between pages (such as an online shopping cart), you are likely passing a session_id around between pages. If someone malscious were to get a hold of that session_id, they could jump in and hijack the session.

    Fortunately for us as designers, these types of attacks on a session management system are quite preventable, as long as the system is designed with security in mind. here's a few precautions you can take to protect yourself from these sorts of attacks:

    1. Never use user names or passwords, or other relevant data as the session_id. This makes it easier for malicious users to hijack your sessions. Also, generating a new session_id for each session allows you to address each session individually.
    2. Always make sure that your sessions time out after a specified period of inactivity. You want to give users enough time to process the content of each page before their session times out, but you don't want sessions to linger long after the user finishes with the site.
    3. Provide users with a "Sign Off" button, which allows them to terminate their session before they leave the site. This also provides a measure of protection that can prevent sessions from lingering after they're out of use.
    4. Map the session_id to another identifier, like the user's IP address (remember not to store it "in the clear" as mentioned before). This prevents users on one computer from hijacking the session from another, although it doesn't make it impossible.

    One way to generate a good solid session_id could be like this:

    use strict; use warnings; use Digest::MD5; my $md5 = new Digest::MD5; my $remote = $ENV{REMOTE_ADDR} . $ENV{REMOTE_PORT}; my $id = $md5->md5_base64( time, # current time $$, # process id $remote); # host and port $id =~ tr|+/=|-_.|; # escape the result return $id;

Further reading:

  1. The W3C has a good explanation of similar issues on session security found here. Read it if you are considering building a site that incorporates sessions or tracking user interaction within your site or realm.
  2. Security and Privacy Topics from the University of Illinois WWW Identification Service.
  3. Web Security Course
  4. Web Application Forensics. Do not pass "Go", do not skip this one. Read it thoroughly.
  5. The WWW Security FAQ, covers HTTP, Java, Javascript, SSL, and more.
  6. Web Server Security Check, which can be used to check your browser's compliance, security, and ability to properly handle sessions in a secure fashion.

There is no "wrong" way to do session management, but there are "strong" ways to do it.

Don't just take the easy path of using cookies or storing the session_id in the URI, without considering the outcomes, and the other possibilities.


In reply to Re: Secure Session Management by hacker
in thread Secure Session Management by glickjd

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others imbibing at the Monastery: (3)
    As of 2020-01-24 01:23 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?
      Notices?