tags:

views:

72

answers:

3

Working on a web based "buying and selling" application with PHP MySQL where users can post adverts for items and services.

Before a new advert is displayed on the system there must be a method of verification to ensure that the user provided email address is correct, and that the advert is legitimate.

I want to send the creator of any new advert an email containing an url which directs to a page whose primary functionality is to receive a posted variable, $advert_id, and to select the advert from the db for updating / editing / deleting.

This variable is embedded in the url with PHP syntax ie. [http://www.example.com?content=modify%5Fadvert&advert%5Fid=2246317%5D.

This part is quite simple to implement, BUT, if a user was to modify this variable called "advert_id=2246317" to any other integer, they can access other posts/adverts in the system.

The system is advert based, and users dont need an account or login to post, so we cannot prompt for a login at the point of verification which would have been convenient.

Any ideas as to how we could protect the adverts/posts in the system from being accessed via the aforementioned url???

Any suggestions?

A: 

You could add a salt to the id and then hash it.

sha1($advert_id . $salt);

Send this to the user in the URL instead of the advert_id, and store it in your database, along with the advert_id.

Then when they click the link, you find the matching advert for that hashed value.

Making the salt a secret is how you keep users from 'guessing' a valid URL that will let them modify an ad that they did not post. Perhaps you could use the users email address, the time posted and/or a name or something that the user enters when they make a post.

mrinject
A: 

Generate a GUID as the advert ID so simple ID guessing attacks are unlikely to succeed.

Aneurysm9
+1  A: 

If visitors will only be viewing that page from the link you send via e-mail, you can include a hash in that address instead of the advert_id — essentially a random, one-time password.

One common and "often good enough" trick for generating such a random password is to take a single, secret, truly random string (I usually use grc.com), concatenate it with the unique advert_id, and hash the whole thing with, say, SHA1(). Like so:

UPDATE advert SET advert_hash = SHA1(CONCAT(advert_id, 'lots-of-randomness-here'))

You could even vary this by adding time(), or (better still) a random number to the end. The outcome is a 40-character string stored in your database that nobody could possibly predict (without knowing the secret data you used to generate it).

For example, I might get this instead of advert_id=1:

f2db832ddfb149522442c156dadab50307f12b62

If I wanted to sneakily edit advert_id=2 (which somebody else created), I'd first have to guess that the hash is this completely different string:

e5c6a3a9473b814b3230ee7923cbe679fcebc922

So, include that in the URL instead of the advert_id (or, if you like, in addition to the advert_id), and suddenly your users are powerless to ruin other people's content.

VoteyDisciple