Let's talk
security

Sites sharing a server: how to stop one hack reaching all

Several websites ran as one user on one server, so one hack reached all. How to check your hosting, and what separating the sites changed.

· · updated

Diagram: Shared pool versus one user per site. One shared user across all sites; One site breached, all followed; 539 MB of backups downloadable; Now: own user, own worker set, own folder

If several of your websites share a server, one hack reaches all of them when they run as the same user: whatever can run code in one site can read and write the files of every other. What stops it is giving each site its own user, its own worker processes and a folder it cannot leave, and then checking that each protection really refuses a request. Start by asking what someone running code in your least important site could read.

Here is what happened on a server we took over.

You run several websites on one server, and the least important one is a demo, a parked domain, something nobody has logged into for a year. It has an out-of-date plugin. An attacker gets in through it, and within the same window your main site is compromised too. The security plugins you paid for never raised an alarm, because it turns out they were not doing anything.

That is what happened on a server we took over. Several sites ran through one shared set of worker processes, all as the same system user. One was compromised, and every other site followed in the same window. The attacker did not need a second weakness. Once code ran as the shared user, every other site’s files were already writable by it.

The cost was every site on the machine at once, plus 539 MB of site backups that had been downloadable by anyone who guessed the address. Restoring a whole estate is a far larger job than restoring the one site that was the way in.

What was actually going on

The default way to run a web server is one service user for everything on the machine. It is the path of least resistance, and you get it if you never think about it. The effect only shows under attack. If an attacker can run code in the process, what can they read and write? On a shared setup the answer is every site. That includes the configuration files that hold each site’s database password, and the upload folders that have to be writable so visitors can send in files.

So the number of sites on the machine multiplies the damage from any single weakness. The forgotten site is always the one that falls, because neglect is what makes it fall, and it is the one nobody thought worth protecting.

There was a second failure, and it is the more general one. The sites carried the usual protection plugins, which write rules to block direct access to upload folders, configuration files and backups. Their settings pages showed them as active. They did nothing at all, because this server does not read those per-folder rule files. That mechanism belongs to a different web server. The rules were written to disk and never consulted by anything.

That is how 539 MB of backups sat publicly downloadable. The plugin that made the backups had written a rule denying access to that folder, and the rule was never read. Anyone who guessed the path had a full copy of the site and its database.

What we changed

Each site now runs as its own dedicated user, in its own set of worker processes, confined to its own folder and nothing else. That gives three separate protections. Separate users mean site A’s files are not writable by the user site B runs as, which is what actually contains a breach. Separate worker sets mean a site that hangs stalls only itself; before, a hung site used up the workers for everything, and we had read that as “the server is down” and blamed capacity, when it was isolation. Folder confinement stops the software opening files outside its own folder, a second line in case permissions were set wrong somewhere, which on any machine with a history they will have been.

The protections that were doing nothing were replaced by one server-level fragment, included by every site: no running of programs in upload folders, no serving of configuration or backup file types, no hidden files. It sits in the layer that actually handles requests. We check it by hand by requesting a file that should be refused and confirming the refusal came from that layer.

The same pass turned up a third trap. The server’s remote-login rules are read from a folder of small files, and the first matching rule wins, in alphabetical order. Our hardening file sorted after a default file supplied by the vendor, so every conflict went the default’s way and ours never applied. There was no error, because the configuration was valid. We renamed the file so it sorts first.

What it did not fix

Separate users cost more to run: more files to maintain, more memory because the worker sets do not share capacity, and a deployment step that must get ownership right per site. We judged that cheaper than restoring an estate.

Isolation does not stop a site being compromised. It limits what one compromised site can reach. Passwords, patching and scanning lower the chance of a break-in, and isolation lowers its cost. You need both, but only one of them still helps on the day you learn the other failed.

How to stop one hack reaching every site

  1. Ask: if someone ran code in one site, what else could they read and write? Answer by listing folders, not by estimating likelihood.
  2. Ask whether each site runs as its own user, in its own set of worker processes, confined to its own folder.
  3. Ask which of your protections you have personally watched refuse a request you made on purpose. Anything you have not seen refuse something is an intention, not a control.
  4. Try to fetch a backup file or a configuration file by its address. Protection plugins write per-folder rule files, and some web servers never read them.
  5. Accept the cost: separate users mean more files to maintain and more memory.

Where this ends up

Taking over an estate like this, separating its sites and checking that each protection really refuses what it claims to, is the work described under enterprise modernisation.

Working on something like this?

We build this kind of software, and we staff the teams that do.

Get in touch