Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to implement an unsubscribe link for your newsletter?

I am thinking that I create a deactivation code put that in the unsubscribe link along with their user id. Then when a recipient of my newsletter clicks the link, I can look up their user id and see if the deactivation code matches.

Does this sound like the best way?

What are some other ways?

like image 446
Tony Avatar asked May 12 '09 17:05

Tony


2 Answers

From an end-user perspective, single-click unsubscribe is excellent.

However, using hash(id + secret) is insecure because a clever attacker can very quickly "brute force" the secret, then proceed to unsubscribe every user in your DB simply by incrementing the ID.

It is much more secure to keep the ID "semi-secret" on the server and use the e-mail address to lookup the user upon unsubscribe. This way, a successful unsubscribe requires pairing an email address with the correct ID. You can make this even more secure by saving a truly secret key for each user and using that instead of the ID. This is especially necessary if the email + ID pairs are published.

So, for example, your unsubscribe link would look like this:

http://mydomain.com/unsubscribe?email={$email}&hash={$hash}

And a server-side function to generate $hash would look like this in PHP:

<?php
function unsubscribeHash($id, $email) {
    $hashSecret = 'Fz!Fx~36N66>io3B-vlPDshdRxos8JjCd4+Ld-s2^ca{19Q/5u';
    return sha1($id . $email . $hashSecret);
}
?>

Then, to complete the unsubscribe, you will lookup the user by email, and verify

$_GET['hash'] == unsubscribeHash($user_id, $_GET['email'])

like image 131
jchook Avatar answered Jan 13 '23 23:01

jchook


You could just use an hashing algorithm to secure the userID (so that nobody can unregister all your DB with a nasty loop).

You'll end up with two params : userID and hash.

The advantage is that you won't need to store any mapping between deactivation code and userID.

like image 37
MatthieuP Avatar answered Jan 14 '23 00:01

MatthieuP