Sorry, kind of a long question. I am hoping that someone smarter about InfoSec than I am will read what I'm doing and give me guidance...
My website allows psychiatrists to track their patient's mental health status. It does this by sending a periodic email to a patient, with a link back to a page on the website that asks the patient to rate various aspects of their mental health (for an example of the types of questions asked, Google "PHQ-9").
The link in the email includes two URL arguments:
- The primary key of a record in the database that identifies both the patient and the doctor
- A random number that must match data that was generated and stored in the Patient record in the database when the email was sent.
Note that the database also contains an expiration date for the most recent email, so the "random number" is only valid for a limited period of time.
Anyone who gets their hands on one of these emails can easily impersonate a patient on our platform by visiting the URL with valid arguments.
Now, a few things are important to note:
The user does NOT need to provide credentials in order to access the page. Anyone who navigates to the page, with valid URL arguments, is presented with the questionnaire. My assumption is that, if someone impersonates a user, the doctor will discover that soon enough when the patient visits the doctor and the questionnaire answers are bogus. Ultimately, the doctor-patient relationship depends on verbal, face-to-face communication. The questionnaire is just additional data the doctor can choose to use or ignore.
Accessing the page does NOT leak patient data. It's a one-way trip from the (presumed) patient's fingers into the website database. The questionnaire does not display any personally identifiable information.
In case someone asks WHY I don't ask for patient credentials, the answer is simple: I want the experience to be as frictionless as possible. I don't want patients to be required to "register" with the website and remember login credentials. The website periodically sends an email to a patient with a link to take an evaluation. The patient clicks the link, and the evaluation appears in a browser window. Done deal. If I require a login exercise then a significant number of patients will simply give up, or forget their password, or whatever.
Is there any obvious security-related flaw with this scheme (other than the risks I've already talked about)? I assume that there are several attack vectors:
Someone might break into a patient's email account. In this case, that person can impersonate the patient, and I have no defense against this. But the worst that can happen is that the bad actor might supply bogus answers to the mental health questionnaires.
Someone might intercept my email on its way to the patient's inbox (e.g. a man-in-the-middle). In this case, the "expiration" feature limits the time frame that the bad actor has to impersonate the patient. This at least prevents someone from using that data after the expiration period has elapsed.
Someone might attempt a brute-force attack by supplying a known valid primary key (discovered from an old email or simply guessed correctly - any reasonably low number is likely to be valid), plus a value for the 32-bit random number. I'm not too worried about this attack.