A small web application typically consists of a web server (e.g. Apache or nginx) and a database server (e.g. MySQL or PostgreSQL).
Often, the two are hosted on a single physical server or on a single VPS (e.g. one running Ubuntu).
When users provide (personal) data to the web application, the application usually makes use of TLS to provide the data in transit.
But what can you do to protect the data at rest, given that attackers may try to get access to your (single) machine and cause a data breach?
Sure, you’ll have the usual access controls, file system permissions, and database access protected by a password.
But if an attacker gets access to the server, it’s most likely via the user for the web server (e.g.
www-data on Apache). If it’s a different user, privilege escalation vulnerabilities have always been found and will always exist, so at one point or another, they will have compromised the root user or
Encrypting data while still on the client side (end-to-end encryption) is not practical for most applications and use cases, since the application needs to be able to process data without the user’s interaction or at least wants to do server-side querying, sorting, rendering, etc.
So you’ll have to encrypt data at the server side, which reduces all security to the question of how secure the keys are.
The problem is that the web server must know the keys in order to be able to process data, or even encrypt incoming data.
If you move the database server to a separate machine, this only provides a benefit if the threat model is that the database server is compromised while the web server is not . Then again, in practice, the web server is more likely to be the weakest link than the database server if you regularly apply patches.
If you encrypt data using the user’s password  , a successful attacker can sit on the server and listen for passwords in incoming requests. So it turns into a matter of detecting compromises as fast as possible.
If you move the tasks of encryption and decryption to a separate machine only responsible for cryptography , your web server will need to be able to talk to it, and any successful attacker will be able to impersonate your web server in talking to the cryptography server.
Regularly, I read about HSMs, but I’ve never seen or used one, personally, don’t know if they are affordable for operators of small web applications, and fail to see how they would protect against an attacker talking to them after the attacker has compromised the web server.
Ultimately, does this mean that there is no real solution, but security is (as always) a process and you have to care about defense in depth, patching vulnerabilities, preventing attacks, detecting breaches, etc.?