#1
  1. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529

    Strategies to activate a website


    I am developing an application like wordpress.com which allows the user to create a basic website. They will enter some information, and then an email will be sent to them like the following:
    Hello Bob,

    Your website bobs_site.mainsite.com has been created, but is not yet active.

    To activate it, please click http://blabla.com/activate.php?id=2&code=1033161cb4c3c1bab4eb95224ff9b08a
    within 2 days of receiving this email.

    Thank you
    The information they will enter will be:
    • Their subdomain name (i.e. "bobs_site")
    • Their name
    • Their email
    • Other stuff


    A surrogate key will then be created for their site name (i.e. "bobs_site") and for the associated user (i.e. Bob).

    Questions...

    • Should I include the surrogate key site ID (i.e. 2) or the subdomain name (i.e. bobs_site) in the URL to activate it (i.e. http://mainsite.com/activate.php?id=2..)
    • Is MD5 adequate for the confirmation code?
    • Should I not even include either the site ID or subdomain name in the URL, and if not, include a more random confirmation code be used?


    Thank you
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,926
    Rep Power
    1045
    The MD5 of what? And what's the goal of putting additional data into the URL? Isn't the token already supposed to be unique?

    Grab a proper random number generator (as discussed last time), generate a random token and use it as a unique activation key. If the activation should be protected, only store the hash of key. No fancy algorithm required, plain SHA-256 is more than enough for random input.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,806
    Rep Power
    529
    Originally Posted by Jacques1
    The MD5 of what? And what's the goal of putting additional data into the URL? Isn't the token already supposed to be unique?

    Grab a proper random number generator (as discussed last time), generate a random token and use it as a unique activation key. If the activation should be protected, only store the hash of key. No fancy algorithm required, plain SHA-256 is more than enough for random input.
    MD5 of either the auto-incrementing site ID or the site name plus a salt, right? Even if it was SHA-256, wouldn't it still be based on the same input? Or is this why you propose a random site ID which the the hash should be created based on?

    Yes I agree that a proper random number generator is good enough, but I typically see "if this link doesn't work, enter bla.php?c=asdf8asdfa8sdf in your browser" Wouldn't a user like to have to enter a smaller random code plus something that they uniquely know such as "bobs_site&code=12314?
  6. #4
  7. Wiser? Not exactly.
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    May 2001
    Location
    Bonita Springs, FL
    Posts
    5,905
    Rep Power
    3969
    Originally Posted by NotionCommotion
    MD5 of either the auto-incrementing site ID or the site name plus a salt, right? Even if it was SHA-256, wouldn't it still be based on the same input? Or is this why you propose a random site ID which the the hash should be created based on?
    Just the auto-inc ID would result in something guessable. All you need is just a random value, doesn't really matter what it is. Adding the site name into the mix wouldn't really improve things any so there isn't much reason to mess with that.

    Just grab a few random bytes from somewhere and then hash that. Save the hash to your DB for later comparison.

    Yes I agree that a proper random number generator is good enough, but I typically see "if this link doesn't work, enter bla.php?c=asdf8asdfa8sdf in your browser" Wouldn't a user like to have to enter a smaller random code plus something that they uniquely know such as "bobs_site&code=12314?
    Even if the link itself is disabled so they can't click it, a user can usually still just copy and paste the value rather than have to enter it by hand. If you want to make it hand-entry friendly then the biggest thing would be just to make sure you use characters that cannot be confused. Base32 would be good for this and would also result in a smaller output than something like SHA-256.

    PHP Code:
    <?php
    //http://stackoverflow.com/questions/14075672/implementing-the-crockford-base32-encoding-in-php
    function crockford_encode$base10 ) {
        return 
    strtrbase_convert$base101032 ),
                      
    "abcdefghijklmnopqrstuv",
                      
    "ABCDEFGHJKMNPQRSTVWZYZ" );
    }

    $bytes openssl_random_pseudo_bytes(4);
    $int unpack('Nint'$bytes);
    $hash crockford_encode($int['int']);
    echo 
    $hash.PHP_EOL;
    4 random bytes stays under the potentional 32-bit number limitation. See the URL in the comment for details on the limitations and work-arounds if you want more length.
    Recycle your old CD's, don't just trash them



    If I helped you out, show some love with some reputation, or tip with Bitcoins to 1N645HfYf63UbcvxajLKiSKpYHAq2Zxud
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,926
    Rep Power
    1045
    All right, I think there's a lot of confusion now.

    First of all, you do not hash the random bytes. Why would you do that? You encode them in whatever format you like. I suggested SHA-256 for securely storing the encoded tokens. It's an alternative to plaintext storage in case you want to protect the tokens, which is not necessarily a requirement.

    Base32 is an option, but truncating the input to only 4 bytes just because of some botched implementation is silly. The conversion of binary strings into different bases is a standard task in IT and not exactly rocket science. If you don't wanna fumble with bits and bytes yourself, grab a library.

    PHP Code:
    <?php

    require_once __DIR__ '/lib/Base2n.php';


    // Base32 encoder using Crockford's alphabet
    $encoder = new Base2n(5'0123456789ABCDEFGHJKMNPQRSTVWXYZ');

    $raw_token mcrypt_create_iv(16MCRYPT_DEV_URANDOM);
    $token $encoder->encode($raw_token);

    echo 
    $token;
    That gives you 26 easy-to-distinguish characters based on 16 random bytes. You can now store the plaintext token or its hash.

    However, encoding is only the first part. Base32 only makes sense if you actually use its features: It's supposed to be case-insensitive, and similarly-looking characters like "1" and "I" are considered actual.

    So before you look up the user-provided token in the database, you first need to normalize it:

    PHP Code:
    <?php

    $token 
    $_GET['code'];

    $normalized_token strtoupper($token);
    $normalized_token str_replace(array('L''I'), '1'$normalized_token);
    $normalized_token str_replace('O''0'$normalized_token);
    If you've stored the token hashes, you have to apply the same hash algorithm now.
    Last edited by Jacques1; February 27th, 2014 at 08:28 AM.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".

IMN logo majestic logo threadwatch logo seochat tools logo