Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've not coded this for myself yet, but I would approach the problem like this:</p> <p><strong>1.</strong> Create a table which can be used to force a validity check when a user presents a cookie for persistence:</p> <pre><code>create table RememberMe ( user_id int(10) NOT NULL, user_token char(10) NOT NULL, token_salt int(6) NOT NULL, time int(10) NOT NULL, PRIMARY KEY (user_id), CONSTRAINT nameYourConstraint FOREIGN KEY (user_id) REFERENCES userTableName (whatever_user_id_equals) ) </code></pre> <p>To populate this table I would add some lines of code to the login, for this example I'll use pseudo-code</p> <pre><code>// userID variable has been sanitized already so // check if user clicked remember me // and if the user logged in successfully: if ( rememberMe == checked &amp;&amp; login() == true ) { // random number to serve as our key: randomNumber = random( 99, 999999 ); // convert number to hexadecimal form: token = toHex( ( randomNumber**randomNumber ) ); // encrypt our token using SHA1 and the randomNumber as salt key = encrypt( token, randomNumber, SHA1 ); // get the number of seconds since unix epoch: // (this will be 10 digits long until approx 2030) timeNow = unix_time() // check to see if user is in table already: sql = "SELECT user_id FROM RememberMe WHERE user_id = 'userID'"; // connect to database: db = new DBCon(); result = db-&gt;query( sql ); // number of rows will always be 1 if user is in table: if ( result-&gt;rows != 1 ) exists = true; else exists = false; result-&gt;free_memory(); if ( exists == true ) { sql = "UPDATE RememberMe SET user_id = 'userID' user_token = 'token' token_salt = 'randomNumber' time = 'timeNow'"; } else { sql = "INSERT INTO RememberMe VALUES( 'userID', 'token', 'randomNumber', 'timeNow' )"; } result = db-&gt;query( sql ); // the affected rows will always be 1 on success if ( result-&gt;affected_rows != 1 ) { print( "A problem occurred.\nPlease log in again." ); quit(); } result-&gt;free_memory(); // create a new cookie named cookiemonster and store the key in it: // (we're not actually storing a score or birthday, its a false flag) set_cookie( "CookieMonster", escape("score="+ userID +"birthday="+ key ); } </code></pre> <p>What this code does is check if the user has checked the remember me and it populates the database table with a key, a token, and a salt for the user as well as a time (so that you can enforce time restraints on the remember me feature).</p> <p>From here you can add code to your website that checks if the <strong>CookieMonster</strong> cookie is set and <em>if it is</em> you can follow these steps to enforce its validity:</p> <blockquote> <ol> <li><p>extract the userID and the key from the cookie presented</p></li> <li><p>Query the database with userID to see if</p> <pre><code> --&gt; a) user has requested to be remembered --&gt; b) check the time to see if they cookie is still valid --&gt; c) extract the token and salt from database table record </code></pre></li> <li><p>Run the token and salt through an encrypt() function call and match against the presented key.</p></li> <li><p>If everything checks out, create a new session and log the user in.</p></li> </ol> </blockquote> <p>Now every time the user comes to your site they will be logged in, and <strong>in the event that their computer is compromised the attacker will not have access to their password</strong></p> <p>Side Note: You should always require your user to present a password when changing their password or email, this way should a user's cookie find its way into the wrong hands your attacker will be unable to steal the account.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload