Leaks in healthcare.

Open laptop on a light background with a blue screen showing a padlock icon and the text "Cyber Attack", illustrating itCraft article on medical data security.

What do hackers actually take from the database?

Medical data is not “just another table in the database”. Two patterns that limit the effects of a leak

In a few weeks, Polish healthcare experienced three serious incidents. First, one of the leading platforms for managing Electronic Medical Records, from which, according to UODO, data of about 19 million Poles leaked (database about 2.5 TB). The leak could have included, among others, name and surname, address, PESEL, contact details, health data, and information about medications and prescriptions. By mid-September, UODO received over 2,000 reports from facilities using the system.

Then another attack on a similar system – potentially up to 5 million people. And on September 24, an attack targeted at one of the medical centers: attackers gained access to part of the infrastructure and some patient data, according to the company about 3% of the entire database. The incidents were, of course, reported to CBZC, CERT Polska, and UODO, and they announced individual contact with the affected parties.

We do not know the technical details of these attacks and do not assess them. However, one lesson is universal: assume that someday someone may access your database. The architectural question is not only “how not to let the attacker in,” but also “what will they see once they are in.” Below are two patterns we use in medical projects: blind index and separation of medical data from others.

Blind index: search by patient without storing them openly

Classic problem: we want to encrypt or pseudonymize the patient identifier, but we still need to quickly answer the question “show all results for this patient.” Encryption with a random IV (e.g., AES-GCM) makes searching with the WHERE clause impossible, as the same value gives a different ciphertext each time.

The solution is a blind index – a deterministic hash calculated with a secret key:
blindIndex(value: string): string {

  return createHmac('sha256', this.blindIndexKey)

    .update(value.trim().toLowerCase())

    .digest('hex');

}

In medical tables, we do not keep the plain userId, only the patientHash column with the index. The flow in the repository looks like this:

Architecture and data flow sequence diagram showing the operation of the blind index mechanism using the HMAC-SHA256 key and the database view after a leak in the itCraft article. AI-generated graphics.

What to watch out for from a technical point of view

  • HMAC, not plain SHA-256. The PESEL or ID space is small – a simple hash can be reversed with a dictionary in minutes. Without the HMAC key, the hash is useless.
  • Separate key for the blind index and separate for encryption. Keys in KMS / vault, never in the same database.
  • Normalize input before hashing (case, spaces), otherwise searching will start “losing” records.
  • Limitations: only equality (no LIKE and ranges), visible frequencies, and key rotation means recalculating indexes – this needs to be planned from the start.
  • Effect: a dump of the medical table is a set of test results and hashes that cannot be pinned to a specific person without a key from another layer.

Separation of medical data from others

The second pattern is the principle that medical data does not live in one “bag” with the rest of the system. We separate three layers:

Databases

  • Domain data is separated from the medical data access log – this is a separate database.
  • The log is recorded outside the transaction of the operation. If the operation is rolled back, the trace of the access attempt remains – and these traces are needed when analyzing an incident.
  • Separate credentials and separate SSL for each database. Taking over the domain application account does not allow reading or “cleaning” the audit log (best practice: the application account has only INSERT rights to the log).

File storage

  • Directory / public space – only content that is served via URL (e.g., graphics, marketing materials).
  • Directory / private space – only ciphertext, without a public URL. Reading is only possible through a prepared method that checks permissions, decrypts the file, and logs access.

Summary

None of these patterns will stop an attacker at the entrance – that’s what updates, network segmentation, MFA, and monitoring are for. It is also extremely important to educate your employees and provide security training. Many attacks succeed not through sophisticated hacking tools, but through simple tricks, phishing, or using passwords from other services.

However, the application of technical data protection measures changes what the attacker takes: instead of a ready file “PESEL + diagnosis,” they get hashes without a key, ciphertexts without a URL, and a log they couldn’t delete. In medical data, this is the difference between an incident and a disaster for millions of patients.

If you are building a system processing health data and want to review its architecture from this perspective – get in touch.

Talk to us

Do you have an idea or a challenge you face every day? We’d love to hear about it. Let’s start with a relaxed conversation about your needs—on your terms and in complete confidence.

    Schedule an interview