0

I'm writing a mailing list manager program. For subscribing and unsubscribing, I'm considering using HMACs of email addresses with secret keys to generate unsubscribe links. This key would be generated one time on the server and then used for all links from that time on. Links would have this format:

https://list.example.com/unsubscribe?address={email_address}&token={hmac(email_address, secret_key)}

When someone subscribes through my web form, my server will send an email with one of these links. When they click the link to confirm their subscription, I need to verify that my server actually sent it.

3
  • On the server side, how would you process the token to find the email address that needs to be unsubscribed? HMAC's are (by design) not reversible - even if you know the secret key. Symmetric encryption (e.g. AES) might work better than an HMAC function for what you are trying to do.
    – mti2935
    Jun 22 at 17:21
  • @mti2935 – The email address is another parameter in the GET request, so it can be verified on the fly.
    – Adam Katz
    Jun 23 at 2:55
  • The email address and HMAC are both included in the URL, and the server already has the key, so the server can check hmac(email_address, secret_key) == hmac_from_url. If that is true, then the link was generated by the server.
    – Someone
    Jun 23 at 2:57

1 Answer 1

1

First, it's good to spell out the problem that you're trying to solve. Then you can determine if an authentication token is necessary and what it needs for proper security.

To prevent user ennumeration attacks that might reveal if somebody is subscribed, make the server's response more vague (see that link).

I otherwise have no concerns about "malicious" unsubscribe actions (unless this is some kind of critical system, in which case: maybe you shouldn't be using email?). I think the easiest accidental unsubscribe comes from forwarded emails, which an auth token doesn't actually alleviate (consider 2FA instead). There is, of course, no harm in including an auth token anyway.

Another risk is that of list bombing, which an auth token would not help. Consider rate limiting, captchas, and/or 2FA to limit list bombs. While confirmed opt-in (COI) limits list bombs to a single message, most lists bombs are COI, so you need more protections or else your system will be abused and anti-spam services will block your mail.

Private or invitation-only lists/newsletters additionally need moderator approval for signups, which easily inserts itself into a COI process.

In the comments, it was established that this is primarily for COI links in order to prove that a subscription request is indeed desired by the subscribing email address (and approved by moderators when necessary). While I believe the HMAC solution is sound here, I'd personally just generate a random code instead. Store it (and the request timestamp) with the user's info in your database and remove the code when the user is verified. To limit clutter and potential abuse, regularly purge unconfirmed users whose timestamps are too old (48h and 7d seem appropriate times depending on your audience).

(If you're more interested in the cryptographic soundness of that concept, I suggest asking Cryptography Stack Exchange instead.)

13
  • No, it isn't critical. I still need some kind of authentication for subscribing, right? I was mostly asking about the cryptographic soundness; is it possible to migrate the question?
    – Someone
    Jun 22 at 20:19
  • You need authentication for subscribing, but I don't see any concern for unsubscribing. Yes, we can migrate this to crypto.SE. I've made a vote to do so, but it needs a moderator or more votes to get it done.
    – Adam Katz
    Jun 22 at 22:05
  • Okay, thank you! Should I update the question to ask if this is secure for subscribing? The only attack i can think of in that case is if someone forwards the subscription confirmation email to someone else (which i doubt anyone will), then unsubscribed, the person they forwarded it to could re-subscribe them.
    – Someone
    Jun 23 at 0:58
  • To elaborate: you might need auth codes for subscribing. If you design it right, they can prevent list bombing. An auth code might similarly prevent unauthorized signups to a private list. However, I don't see auth codes as ideal solutions to those problems. (Consider rate limiting, captchas, moderator approval, and/or 2FA.) Define your problems first, then see if your solution actually makes sense.
    – Adam Katz
    Jun 23 at 2:53
  • This isn't a list that people can send to; it's a newsletter.
    – Someone
    Jun 23 at 2:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.