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

    Join Date
    Sep 2006
    Posts
    1,799
    Rep Power
    529

    Allowing non-logged on users to update records


    I am implementing a type of message system. I have two options:
    1. User 1 logs on to the system and creates a message, and the message is assigned an auto-incrementing key. A link is generated which contains the message ID, a hash which contains the message ID and some data, and sent to User 2. When User 2 (who isn't necessarily logged on) clicks the link, the message is updated based on the data if the hash is correct.
    2. User 1 logs on to the system and creates a message, and the message is assigned a random key. A link is generated which contains the message ID and some data, and sent to User 2. When User 2 (who isn't necessarily logged on) clicks the link, the message is updated if the message ID exists.


    Any recommendations on the best approach (or a third approach)? Thanks
  2. #2
  3. Confused badger
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Mar 2009
    Location
    West Yorkshire
    Posts
    1,047
    Rep Power
    487
    I personally wouldn't give any access to a user's "private" messages unless the recipient could verify who they were (i.e. logged in).
    "For if leisure and security were enjoyed by all alike, the great mass of human beings who are normally stupefied by poverty would become literate and would learn to think for themselves; and when once they had done this, they would sooner or later realise that the privileged minority had no function and they would sweep it away"
    - George Orwell, 1984
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Mar 2006
    Posts
    2,396
    Rep Power
    1688
    This mechanism sounds a little like some of the 'forgotten your password?' options, where you get sent a link and a code (sometime the link itself is temporary and per-user). On that basis I don't think one could object to the basic principle. The difference is that details are going to a 3rd party and that you have no control over what is done with the data.
    I am sure Jacques could give you the ins and outs of how having those pieces of information could open up a backdoor into some of the inner workings of the system!
    The moon on the one hand, the dawn on the other:
    The moon is my sister, the dawn is my brother.
    The moon on my left and the dawn on my right.
    My brother, good morning: my sister, good night.
    -- Hilaire Belloc
  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Hi,

    the description is rather vague.

    What kind of messages? Why and how are they updated by other users? How is the link sent? How is the hashing in the first option supposed to work?

    In general, knowing a strong random number is sufficient proof of identity if both you and your users treat the number like a password.

    That is:

    • The numbers must not be stored as plaintext. They need to be hashed like every other password. You don't need bcrypt, though. Something like SHA-256 is enough, because the passwords themselves already make a brute-force attack infeasable.
    • Your users must not accidentally share the link. You should point this out and also give the URL parameter an appropriate name like "secret".
    • Your users need a way to manage the links. In particular, they need the ability to invalidate them in case they've accidentally shared a link.
    • The links should expire after a while. If appropriate, they should also be deactivated after first use.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,799
    Rep Power
    529
    Originally Posted by Jacques1
    the description is rather vague.

    What kind of messages? Why and how are they updated by other users? How is the link sent?
    An email goes out with "Hello John, Will you be submitting pricing for the maintenance of the ABC building? Please update your status by clicking Yes or No.

    The links would be created using:
    PHP Code:
    //Store in message in database using $message_id as the PK
    $message_id bin2hex(mcrypt_create_iv(16MCRYPT_DEV_URANDOM));
    //Send an email with the following:
    $link="<a href='http://mysite.com?message_id={$message_id}&response=yes'>Yes</a>"

    Originally Posted by Jacques1
    How is the hashing in the first option supposed to work?
    I don't think I am going this route, but it would be something like
    PHP Code:
    $message_id=123;
    $response='yes';
    $salt='3ad9asd';
    $hash=hash('sha256',$message_id.$response.$salt);
    $link="http://mysite.com?message_id={$message_id}&response={$response}&hash={$hash}"
    Great points about managing and expiring links! I am a little confused on the first one.
    Originally Posted by Jacques1
    The numbers must not be stored as plaintext. They need to be hashed like every other password. You don't need bcrypt, though. Something like SHA-256 is enough, because the passwords themselves already make a brute-force attack infeasable.
    My intention was to store all the messages in a database with the PK as a strong random number. What numbers are you referring to as being hashed, and what password are you referring to?

    Thanks!
  10. #6
  11. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Originally Posted by NotionCommotion
    An email goes out with "Hello John, Will you be submitting pricing for the maintenance of the ABC building? Please update your status by clicking Yes or No.
    Sending out plaintext emails which might loiter on some server for an indefinite period of time of course isn't the most secure medium. On the other hand, this doesn't sound like super-critical data. So it should be OK as long as you take care of the issues mentioned above.



    Originally Posted by NotionCommotion
    //Send an email with the following:
    $link="<a href='http://mysite.com?message_id={$message_id}&response=yes'>Yes</a>";[/PHP]
    On a side note: Does it really make sense to have a "no" option? Isn't that the default action if the user doesn't do anything?



    Originally Posted by NotionCommotion
    I don't think I am going this route, but it would be something like
    PHP Code:
    $message_id=123;
    $response='yes';
    $salt='3ad9asd';
    $hash=hash('sha256',$message_id.$response.$salt);
    $link="http://mysite.com?message_id={$message_id}&response={$response}&hash={$hash}"
    No, this makes no sense. Everybody knows the message ID and the response, and everybody can calculate SHA-256 hashes. So the only thing that stops people from faking the URL would be the "salt". Why not leave out all the useless data and only use the "salt"? That would lead to the random ID.



    Originally Posted by NotionCommotion
    I am a little confused on the first one.My intention was to store all the messages in a database with the PK as a strong random number. What numbers are you referring to as being hashed, and what password are you referring to?
    The message ID is a kind of password, because knowing it gives you access to the message. That means you have to protect the ID by hashing it.

    Imagine somebody breaking into your database server. If all message IDs are stored as plaintext, the attacker can update any message they want. But if the IDs are hashed, this isn't possible.

    So generate the ID, send it out as plaintext and then store its SHA-256 hash. To check an incoming ID, simply hash it.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,799
    Rep Power
    529
    Originally Posted by Jacques1
    No, this makes no sense. Everybody knows the message ID and the response, and everybody can calculate SHA-256 hashes. So the only thing that stops people from faking the URL would be the "salt". Why not leave out all the useless data and only use the "salt"? That would lead to the random ID.
    I guess my thought was it would create a unique hash for ever message. Doesn't make sense?

    In regards to the rest of your post, thank you, I understand.
  14. #8
  15. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,911
    Rep Power
    1045
    Originally Posted by NotionCommotion
    I guess my thought was it would create a unique hash for ever message. Doesn't make sense?
    Hashing a random number together with some "public" data has zero benefit over simply using the random number directly. The uniqueness is guaranteed by the database in either case (the message ID is the primary key). And adding known data to a secret doesn't make it more secret.

IMN logo majestic logo threadwatch logo seochat tools logo