The medical exams backend was secured by encrypting sensitive data at rest and in transit, replacing generic permissions with role-based access control, and logging every access in an audit trail. Built on PHP (Laravel), MySQL and Apache, the system now keeps 100% of sensitive data encrypted, and patients reach their results through a portal with role-based permissions and full traceability.
| Client | Clinical laboratory |
| Confidentiality | Client name, screenshots and links are omitted at the client's request. The diagrams describe the solution and the techniques applied. |
| Industry | Healthcare and clinical analysis |
| Service | Cybersecurity |
| Stack | PHP, Laravel, MySQL, Apache, HTTPS/TLS, Role-based access control (RBAC), Encryption at rest, Audit logging |
| Our role | Security audit, redesign of the permissions model, implementation of encryption and traceability, and production deployment. |
| Published | September 11, 2025 |
A medical exams platform handles information that has real consequences when it leaks: lab results, patient identifiers and contact details. This case study explains how its backend —PHP with Laravel, MySQL and Apache— was secured after a previous security audit, without taking the platform down or changing how the laboratory works day to day.
This is not a story about new features. It is about changing the rules of the system: what each role can see, how sensitive data is stored and how you prove later who looked at what. Under our confidentiality agreement, the client name and application screenshots are not published; the two diagrams summarise the technical decisions.
The challenge: a live system holding data that cannot leak
The platform had been running for years and the team knew the business inside out: front desk, laboratory and administration used it every day. The problem was not how it was used but how it was designed. The system had grown by accumulation, and nobody had reviewed the permission model or the way data was stored from a security standpoint.
Permissions set by habit, not by a model
Access had been granted as it was needed, so several internal profiles could read information they did not need for their work. Without a declared role model, it was also hard to say who should be able to see a result and who should not: the answer lived in the team's memory, not in the system.
Sensitive information stored in clear text
The database and the backups kept patient identifiers in clear text. Any unauthorised access to the server, to a backup or to a database dump would expose that information directly: there was no second barrier behind the first one.
No record of who looked at each result
Opening a report left no centralised trace. If someone accessed a result they were not entitled to see, there was no way to reconstruct it afterwards, and that is exactly what an audit or a patient complaint calls for.
The solution: encryption, roles and traceability
Before writing any code we decided which information is genuinely sensitive and what each profile needs in order to do its job. With that map we redesigned the permission model and added two new layers: data encryption and audit logging. The application stayed the same —Laravel on Apache, with MySQL— but every request now goes through an explicit access check.
Encryption at rest and in transit
Sensitive identifiers are stored encrypted, backups included, and all traffic runs over HTTPS end to end. Encryption is layered —first the channel, then the storage— so that a slip in one layer does not leave the information exposed in the next.
One permission per responsibility, not per person
Each profile —front desk, laboratory, administration and patient— gets the minimum permissions it needs. Role-based access control is enforced on the server, on every request, not in the interface: even if someone crafted a request by hand, the application would still answer with a denial if their role does not authorise that record.
Traceability: every query leaves a record
The system notes who opened each result, with date, resource and IP address, in an append-only log: the application writes but cannot edit or delete entries. That is the evidence that lets you reconstruct an access months later and, more importantly, it means nobody can look at a record without leaving a trace.
How we implemented it without stopping the service
The backend was in production and could not be taken offline: patients expect results every day. So the plan worked in layers with a rollback ready, and everything was tested first on a copy of both the database and the application.
Data map and priorities
We identified where each sensitive piece of data lives, who uses it and what would happen if it leaked. That priority list decided what to encrypt first and which permissions to adjust without interfering with the laboratory's daily work.
Layered changes with a way back
First HTTPS across the site, then encryption of sensitive data and backups, and finally the reorganisation of roles. Each step was tested on a copy before going to production, with a short maintenance window for the deployment.
Verification before signing off
Every change was checked with two questions: can the right user still do their job, and can the wrong user no longer do it? We also reviewed dependencies, credentials and server configuration, which is where the gaps nobody looks at usually hide.
Results
The platform works the same for the people who use it every day, but access to sensitive data is now explicit, encrypted and logged. These are the changes compared with the starting point the audit found:
| Item | Before (audit) | After |
| Sensitive data stored | In clear text in the database and backups | Encrypted at rest, backups included |
| Access permissions | Granted by habit, with no role model | Role-based access control with least privilege |
| Traceability of a query | No centralised record | Audit log: user, resource, IP and date |
| Data transport | No guaranteed encryption on all traffic | HTTPS/TLS across the site |
The result we value most is not a number but the ability to answer an uncomfortable question with data: who looked at a specific patient's result, and when. That answer now takes seconds — and it is why 100% of the sensitive data the platform stores is encrypted.
What to review if your system handles healthcare data
In our experience, these are the points that separate "having permissions" from truly controlled access:
- Declared roles, not improvised ones. Every profile should have in writing which data it needs, and the system should enforce it on the server on every request.
- Encryption in both directions. At rest (database and backups) and in transit. With only one of the two, a single slip leaves the data in the open.
- An audit log that cannot be rewritten. It should record who, what, when and from where, and the application itself should not be able to modify or delete entries.
- Encrypted, tested backups. A backup that has never been restored is not a backup: it is a folder full of hope.
- Up-to-date dependencies and server. Many breaches do not come through a door you built, but through an old component nobody updated.
If your platform stores patient data and you cannot answer these questions with confidence, our cybersecurity page explains how we work, and if you prefer to talk about your own case you can get in touch and we will review it with you.
Frequently asked questions
How is patients' sensitive data protected?
With encryption at rest — data is stored encrypted in the database and in backups — and encryption in transit, because all traffic runs over HTTPS. Access does not depend on each person's password: every role has specific permissions and every query is logged.
What is role-based access control and why does it matter in healthcare?
It is a model where permissions depend on the role — front desk, laboratory, administration or patient — and not on each person's judgement. In an exams platform it prevents people from seeing results that are not theirs to see: whoever publishes a report does not need to read a patient's full history.
Can this be applied to a system that is already in production?
Yes, and that is usually the case. It starts with a data map to locate sensitive information, then encryption is layered in without taking the service down, permissions are reorganised, and everything is tested on a copy of the database before touching production.
What does a security audit of a healthcare backend cover?
Authentication and session management, permissions per role, encryption at rest and in transit, credential and secret management, backups and their restore process, audit logging of every access, and updates to both the dependencies and the server itself.
