Every app in its own sandbox
How Tanzahost keeps each app apart - a normal user, no extra powers, read-only system files, its own disk and network - and what's still a risk.
Updated 17 Oct 20266 min read
On shared hosting, your neighbour is the biggest danger. Not because they mean harm, but because once someone breaks into their old WordPress plugin, the next thing they look at is yours.
So the first promise Tanzahost makes is simple: a broken-into app is a dead end. Every app runs in its own sandbox, and every rule of the sandbox closes one way out. This post walks through those rules, why each one is there, and the risk we haven't removed.
A normal user, with no extra powers
Inside its sandbox, your app runs as an ordinary user called app, never as the administrator (root). That one choice removes most of the classic tricks, because most of them need administrator rights to start.
On top of that, the sandbox drops every extra power the operating system can hand out: changing the network, loading code into the system, reading other processes' memory, and the rest. It also can't gain new ones later. A program that tries to raise itself to administrator, even through a file that's marked to run with more rights, gets nothing.
Commands like composer install or php artisan migrate work as always; apt-get install doesn't, on purpose. If your app needs a system package, you ask for it in tanzahost.json, and we add it when we build the app, outside your running sandbox.
Read-only system files
The system files your app sees are read-only. An attacker who gets in can't replace a system program with their own, plant something that runs at the next start, or change how names are looked up.
Your app still has places to write:
| Place | What it's for |
|---|---|
/home/app | Your app's own home folder, on its own disk |
/tmp | A small private temporary folder, for this sandbox only |
| Permanent folders | The folders you choose, like Laravel's storage, kept across deploys |
Everything else is fresh on each deploy. If someone changes a file in your code folder, the next deploy puts the real one back.
Its own disk, and its own limits
Each app has its own disk. It isn't a folder on a shared disk that one runaway log can fill for everyone: it grows ahead of your app's use, so it never fills the server and hurts its neighbours.
Each app also has limits that you set: the most memory and processor time it may use, with no swap behind the memory, and a cap on how many processes it may start. Limits cost nothing by themselves. They stop a runaway app (or a "fork bomb") from emptying your wallet or slowing the apps next to it. We wrote about why in Why we charge for what apps use.
Its own network
Each project gets its own private network. Asha's shop, duka, has a web app, a worker and a MySQL database: they reach each other, and nobody else reaches them.
There are two locks on that wall, not one. The sandbox keeps projects' networks apart, and our own firewall rules, written separately and tested on a real server, drop traffic between projects too. If one lock ever fails, the other still holds.
Going out, your app can reach the internet, so payment APIs, email providers and package registries work. What it can't reach:
other customers' apps and databases;
the server it runs on, on any of its addresses;
our private network;
the private and special addresses where cloud machines answer questions about their own secrets;
port 25, so a broken-into app can't send spam directly. Use an email provider on port 587 or 465.
New outgoing connections are limited per app too, so one app's abuse can't get the address it shares with others blocked.
Coming in, your app has no public door at all. Visitors reach it only through our front door, which passes every visit through a web firewall and limits first. Your databases are closed to the internet too: only your project's apps can reach them. The one exception is yours to make: you can switch on connections from outside for one of your own databases, to use your own tools, and then it takes only encrypted connections, through our front door, never a door of the server it runs on.
Builds, imports and the terminal are sandboxed too
The rules don't stop at running apps.
Builds run in their own sandbox, with time and memory limits, and with no way into our private network. Each app has its own build cache, never shared with another customer, so nobody can poison your build by planting a package in a shared cache.
Database imports run in a throwaway sandbox that reaches only the database being imported. A dump file can carry commands that run programs or read files on the machine that imports it, so we treat every dump as hostile.
The terminal opens inside your app's sandbox, as the same normal user, with the same walls. The start and end of every session are logged.
The file manager works only inside your site's folder. A test tries to reach files outside it, and must fail.
Nothing that tells an attacker what runs it
You won't find the names of our tools anywhere: not in your app's files, its build logs, its host name, its environment variables or its list of folders. We write the sandbox's own system files ourselves, and we clean our tools' lines out of the build output, so you see your own steps, like "Running composer install", and nothing else.
This isn't secrecy for its own sake. An attacker who knows exactly what software stands between them and the next customer knows exactly which known weakness to try. Telling them less is a cheap, real defence.
To be honest about it: someone with deep Linux skills and a terminal can sometimes guess the technology behind any hosting platform, ours included. Our rule is that we never tell them, and nothing we show gives it away.
How we check it
Each rule has a test. A test app looks for every clue we promised to hide, and must find none. Other tests try the ways out: becoming administrator, reaching another project's network, reaching the server, reaching the private addresses. They run before any change to the sandbox goes in, and they've been run on a real server, not only on a developer's laptop.
The risk that's left
Apps on the same server share one operating system core, the part that runs every program. Every wall above is built by it. If a serious flaw is found in that core, a skilled attacker could use it to climb over the walls. That's the main risk that remains, for us and for every host that runs many customers on one server.
What we do about it:
We keep servers patched, and the rules above shrink what an attacker can touch while they look for such a flaw: no extra powers, no administrator, read-only system files, almost no network.
We measured a stronger wall, which puts its own layer between apps and that core. It made web pages several times slower on our real servers, so new apps run in the standard sandbox for now. The stronger one stays built and tested, one setting away, if the balance changes.
No sandbox makes a hacked app safe for its owner: if your WordPress admin password leaks, the attacker gets your site. What the sandbox promises is that it stops there. Your neighbour's bad day stays your neighbour's.
More on our security page.