views:

514

answers:

5

I'd like to customize the "unsubscribe" links in our email newsletters so that they remove the recipient with a single click. Right now they just point to a generic page where the user has to enter their email address and select the newsletter from which they'd like to unsubscribe.

It seems like this should be pretty straightforward, i.e. just include the email address and newsletter id as url parameters. But when I looked at examples from the lists I subscribe to, many don't include a recognizable address and most appear to be using what looks like guids and/or hashed values in the parameters. From that, I'm guessing that I should be hashing or otherwise encoding some information to prevent malicious abuse of the unsubscribe form.

So my question is really about best practices and not reinventing the wheel. Is there a standard way to handle this sort of functionality? More specifically, are there reasons not to include the recipient's email address as part of the url? This seems just simple enough that it feels like I'm overlooking something.

+6  A: 

You can encode a URL like so:

http://yourserver.com/unsubscribe/<encoded-email>/<expiration>/<signature>

Where <signature> is something like HMAC(secretkey, "<encoded-email>/<expiration>"). Encoded-email can just be a URL-encoding of the email, or it can be an actually encrypted (AES+CBC+Base64 or similar) version of the email. Using full encryption would seem to be of little use though - since the person receiving this has their own email address anyway.

This signature scheme has the advantage of not needing any database storage, while remaining secure against malicious attempts to unsubscribe someone.

Alternately (or in addition to the above), you can send a confirmation mail out to confirm the user's intent. This avoids problems if the user forwards the email.

bdonlan
So if I understand, you're basically saying to include emailaddress, and a hash of emailaddress+secretkey in the unsubscribe link; then my unsubscribe web page will rehash emailaddress+secretkey and make sure it matches the hashed value passed to the page. And this prevents abuse because the secretkey value exists only on our server. That makes sense so far, but what's the purpose of <expiration>?
Matt
@Matt, expiration is to ensure these urls don't need to remain secret forever and a day. :)
bdonlan
Matt
I mean, it expires so if it's posted publicly, the window of time in which it can be used to unsubscribe that person is limited. This is mitigated if you use a confirmation mail, of course.
bdonlan
Got it. I spent some quality time with google and MSDN, and an HMAC looks like just what I wanted but didn't know how to ask for. Thanks again.
Matt
Here's an example of using HMAC in C#: http://buchananweb.co.uk/security01.aspx
Atømix
@bdonlan <expiration> - is it encoded DateTime value (like email address)?
kilonet
Yes, it's an encoded date. Unix time would work well here.
bdonlan
+2  A: 

If your mailing list software uses old-school best practices, there should be an 'unsubscribe' email address - emailing to that address from the address you want to unsubscribe (possibly with a fixed subject line) generally does the trick (along with sending a confirmation email). In that case, adding a properly formatted 'mailto' link should do the trick.

Harper Shelby
I like this approach, but I'm dealing with an existing code-base and architecture that makes it easier to go the web-based route.
Matt
+1  A: 

Two reasons for not having a plain text email address in the query the in the URL are that you don't want malicious users unsubscribing your customers from your mailing list.

The second which probably would only affect companies sending millions of e-mails, is to make it harder for spammers to 'sniff' for genuine email addresses.

Phil Carter
A: 

It's not safe to embed email addresses in a newsletter. Not sure about yours but many newsletters ended up in some archive on the web. There are spam bots specifically designed to harvest addresses from mailing list archives.

Email is a safer technology for this. Setup a mail account for unsubscribe and get Email address from mail headers. If you use any mailing list software, it should handle this already.

ZZ Coder
A: 

I give each email I send an ID, then look up the email ID when they click unsubscribe.

http://www.foo.com/unsubscribe.asp?ID=1234

And then unsubscribe the email address I sent 1234 to.

Jim