Re: Safe session IDs (Summary)

From: Ryan M Harris (rmharrisat_private)
Date: Mon Jan 14 2002 - 10:38:54 PST

  • Next message: infosat_private: "Network library lcrzo 4.03"

    Like I stated previously, thank you all for the help.  In case you were
    wondering what this is for, my current employer commissioned the creation of
    a secure web programming class for PHP (url:
    http://sourceforge.net/projects/cwpapi/).  This session handler is part of
    that class.
    
    I have summarized below the conclusions I have arrived at, and the reasons.
    If you do not agree with them, PLEASE contact me.  I VALUE THE INPUT. Some
    of the ideas I arrived at may seem to contradict what some on the list have
    said, but please do not feel offended.  Read why I did not take all of the
    advice or why I did take a particular piece.
    
    Issues with Session IDs
    =======================
    
    1. Must be unique.
       a) Logically we ensure this through the MD5 hash and the sheer amount of
    data introduced into the system.
       b) In case we don't have a unique ID, it doesn't really matter.  When we
    go to assign one any well behaved session manager should check to see if a
    session id is in use before allocating it to another user.  Any programmer
    knows that the less left to chance, the better
    
    2. Must have an expiration set.
       a) I had one person suggest that the expiration be set in the cookie
    using (I believe) the SHA algorithm, this would make the expiration in
    theory un-alterable.
       b) In my ideas, I say the session handler should store this on the server
    end.  In theory if they can break into the server to change the expiry, all
    bets are off anyway.
             1) I say, store in a database structure:
                   Fields  (simplified)
                   SessionID
                   Expiry
                   Data
    
    3. Must be non-guessable.
       a) Must be random.  I have received a general consensus that doing a hash
    based on previously generated IDs is the best way to go.
       b) I would love to use a product like yarrow, but I can't expect the
    users to have access to the machine or have a sysadmin on the other end that
    is willing to install something like that.  So I have to resort to other
    means of data collection.  I am still working on this, once I get a way, I
    will get back to you.
       c) In my thoughts the IP address scheme below _tends_ to make a session
    id even harder to guess (note the "tends").
    
    4. Must be secure.
       a) I said SSL and others said SSL therefore let it be ssl!
    Unfortunately, I cannot require people using this to use SSL.   BUT I want
    any security holes in implementation to be a result of them making a
    conscious choice to ignore my advice.
    
    Current Idea for Implimentation
    ===============================
    
    Kill all records in the table that have expiry > time()
    
    Check to see if a session ID was returned as a cookie.
    
    ->If not, we issue one as a cookie and store the following info in our list
    in the database: SessionID, Expiry, Data, Remote IP, Remote User Agent.
    
    ->If so, we do a check to see if we have it in our database.
    
    ->->If we do have it in our database, check to see if the IP address, User
    Agent that the user returned matches what we have. (what this accomplishes
    is sometimes questionable, if you are behind a proxy, then people behind the
    same proxy could steal your session id and this could not detect.  But for
    those NOT behind a proxy, we cut down on the likelyhood someone can fiddle
    with it)
    ->->->If their IP address matches, look up the session data and update the
    expiry in the database. (so that it extends the time until it expires)
    ->->->If their IP address does not match, issue a new session ID just like
    we did when none was provided.  In this way, randomly picking session IDs
    doesn't do anything.  You also need to know what IP address the person was
    on when the session was created.  Session ID itself does not tell you.
    
    ->->If we do not have it in our database, then we issue one just like we did
    when none was provided.
    
    NOTE: Of course we build in some checks to ensure that someone doesn't try a
    DoS by getting the server to keep issuing new session IDs.  (although this
    whole process only takes about .01 msec to do on our test system so a DoS
    with it doesn't seem likely.)
    



    This archive was generated by hypermail 2b30 : Mon Jan 14 2002 - 14:22:50 PST