Protecting encrypted data in case of SQL injection

If I understand your question correctly, your system uses the same key to encrypt and decrypt the message for both patient and doctor.

In which case your attack is theoretically possible assuming you could read another user's message and insert it into the DB as your own message.

Mitigation in terms of encryption against this would be a unique key per user or using public/private key pairs to encrypt the data with each user again having a unique key for additional security and limitation of damage in the event of a breach.

Other mechanisms would include appropriate defence against SQL injection by sanitising input and also a user verification system to ensure any registering user is a legitimate patient, this reduces the pool of attackers but shouldn't be relied on alone.


The problem here is that every note is encrypted with the same encryption key. That makes the app more vulnerable than it would need to be.

Consider this setup instead:

  • Every user, doctors and patients alike, have their own public - private key pair.
  • Public keys are stored encrypted with an application wide key stored outside the database..
  • Private keys are stored encrypted with a personal key derived from the users password.
  • Every single note is encrypted with it's own unique random key. That key is stored encrypted in two version - one encrypted with the patients public key, and one with the doctors public key.

Don't take this as a blueprint for the perfect system. There are many ways to do this, and possibly better ones than this. But it is an example of a system where read and write access to the database only (e.g. in the case of SQLi) would not instantly give the attacker access to all the plaintext data.

Edit: If you want all doctors to be able to read all notes, things get a bit more shaky. Anyone with write access to the entire database will be able to turn themself into a doctor. So you need to restrict write access to the doctors table as much as possible!

Don't give the DB user the web app is using write access to that table, and use another more restricted system (e.g. only available on some intranet) to create new doctors. Or require that every row in the doctor table is cryptographically signed or something like that. Or even better, read Lie Ryans great answer.

Conclusion: The take away lesson here is that crypto requires more than just an algorithm, a message and a key. It's when you start thinking about how to handle the keys things gets complicated, and you need solutions that are heavily context dependant.


I think you're getting too sucked into a specific attack. I mean, you're worried that a SQL login that has full CRUD access to the notes table (and possibly more?) will try to read other doctors' notes?

  • What if they selectively delete a note for a specific day?
  • What if they replace a doctor's note with one they created?
  • What if they change which doctor issued a note?
  • What if they scramble all the notes and try to pull a ransomware threat?

Yeah, it'd be good to encrypt the doctors' notes using different keys (even if it's just as simple as: [AppWideKey]+[DoctorID]) But your focus should probably be, "If a SQL Injection Attack succeeds, the hacker will be logged into SQL as AppUserX. How can I minimize the damage that AppUserX can do?" And the answer's usually: have them use Stored Procedures to get to their data, only let the stored procs do the minimal amount to accomplish the app's needs, and don't give the user direct access to the tables.