php - Is using a UUID in a newsletter unsubscribe link, secure enough?

Viewed 264

I'm working on a php newsletter script. I've got a MySQL table of subscribers where each user has a UUID assigned and wondered if using it in the unsubscribe link would be secure enough.

I build it by replacing the href attribute together with the query and the UUID that matches the user's email:

// Get UUID based on submitted email

$link = "href='https://example.com/unsubscribe.php?id=$uuid'>unsubscribe</a>)";

$html_message = file_get_contents('welcome_template.html');
$html_message = str_replace('href="">unsubscribe</a>', $link, $html_message);

// Headers and stuff

mail($email, $respond_subject, $html_message, $headers, '-fhello@example.com');

By secure enough I mean if it is considered a bad practice and if it's "easy" to predict the UUID after some queries.

This answer to a similar question states that

A simpler method is a random string of a specific length (e.g. 30 chars) stored in a table with a unique constraint on that field.

Is a UUIDa valid random string?

1 Answers

Predictability depends on which version of UUID you're using:

  1. Easily predictable if they have samples generated on the same machine at around the same time.
  2. Easily predictable if they have samples generated on the same machine at around the same time.
  3. Very easily predictable if you publish your namespace UUID
  4. Completely unpredictable
  5. Very easily predictable if you publish your namespace UUID

MySQL's UUID() function produces V1 UUIDs, but there are other generators to get the other versions if desired.

However, in your specific use case, there is the additional issue of discoverability. If I want to unsubscribe another user from your newsletter, then the first thing I'm going to do is look around in other parts of your UI to see if you expose the target's UUID, email address or whatever other key you choose, and then predictability doesn't matter.

This is why many such systems don't bother securing this surface and instead send a confirmation email to the unsubscribed user, with a link to either "click to confirm" or "click to undo" depending on how likely you think attacks or mistakes will be vs legitimate requests. And that link should include a random, unique identifier generated for that specific unsubscribe request so the attacker has no hope of guessing it.

Related