Open cdriehuys opened 6 years ago
This issue appears to be really difficult to solve, so for now I want to focus on not exposing email addresses for "unsecure" endpoints. This means the registration and password reset endpoints. The other endpoints are theoretically more trackable since you would know which user is performing those actions.
I think we can use UUIDs to solve this problem. Since we don't have to hit the database to generate a UUID for an email, we can return an ID even if the email address wasn't actually persisted.
The other problem we have to solve is not exposing registered email addresses when authenticated users attempt to add a new email address. Right now, they could just attempt to add an email address, then list their email addresses. If the new email does not appear in their list of emails, then it has already been registered.
If we truly want to avoid leaking information about the existence of email addresses we need to refactor the
EmailAddress
model.The Problem
Consider the case where a user has already registered the email
foo@example.com
. If another user tries to add that email to their account, we must save a duplicateEmailAddress
instance so that we can return itsid
attribute in the response. Without theid
, users could determine the existence of other email addresses by simply seeing if theid
field is non-null after attempting to add that address.The Solution
In order to include the
id
attribute in the response, we have to actually create a newEmailAddress
instance and save it. This will require removing the uniqueness constraint from theemail
field. We will also have to do our own uniqueness checks when registering a new account and adding an email address for a user.This also introduces the problem of having
EmailAddress
instances that can never be verified since they are duplicates. We would then need a management command for clearing out these useless instances.