Problem: When working on Dalza, an application that handles sensitive medical data, I quickly realized that security could not be an afterthought. Due to the highly sensitive nature of patient data, medical applications are prime targets for attackers, and even minor vulnerabilities could lead to data leaks, compliance violations, and reputational damage.
One key risk was enumeration attacks, in which attackers attempt to identify valid usernames or emails through subtle variations in system responses. Another was timing-based attacks, which exploit differences in response times to infer sensitive information. Finally, storing unencrypted personally identifiable information (PII) poses a risk in case of a data breach.
Solutions & Implementation:
Standardized Error Messages to Prevent Enumeration Attacks
To limit enumeration attacks, it is crucial to use standard and generic error messages that do not reveal whether a username, email address, or other sensitive information exists on the system. Attackers often exploit inconsistencies in authentication responses to identify valid accounts, which can be used for further attacks such as credential stuffing or phishing. For example, instead of returning different messages for “Invalid username” and “Invalid password,” the system should respond with a generic message such as “Invalid credentials,” regardless of whether the username exists. Similarly, password reset and account registration flows should avoid revealing whether an email address is registered with the system.
Constant-time comparisons
to mitigate timing-based attacks. Timing attacks exploit the fact that string comparisons used in authentication can take slightly different amounts of time depending on how much of the input matches the correct value. Attackers can measure these differences to deduce valid credentials. To counteract this, I implemented constant-time comparison functions for authentication, ensuring that password and token verification always take the same amount of time, regardless of input.
Encryption with ActiveRecord::Encryption
for all necessary database attributes, ensuring that all personally identifiable information (PII) data was securely encrypted at the database level. Storing unencrypted personally identifiable information (PII), such as names, addresses, or medical records, poses a massive security risk. Even if the database is breached, proper encryption ensures the data remains unreadable without the correct decryption keys. I implemented ActiveRecord::Encryption, which provided transparent, field-level encryption for sensitive attributes. This ensured that PII remained securely encrypted even if someone accessed the raw database.