Security model
How HF Panel keeps hosting accounts apart, limits what runs as root, signs updates and protects sign-ins, sessions and API tokens.
This page explains how HF Panel is built to keep your server and your customers safe. It is for administrators who want to know what the software does for them, and for security researchers.
Each account is its own Linux user
Every hosting account is a separate Linux user, in its own home folder /home/<user>/.
- Each account has its own PHP-FPM pool, running as the account's own user. A website can read and change only its own account's files.
- SFTP, SSH, cron jobs, Node.js, Python and Ruby apps all run as the account's user too.
- The File Manager, HF Files and the web disk do their work as the account's user. They never follow a symbolic link
to a place outside the account's home folder, and archives are checked before anything is unpacked: names with
.., absolute paths and links that point outside the folder are refused. - HF Studio never signs in to a database server as root. It uses a hidden login per database that can reach only that database, with a new random password each time it opens it.
- Server Admin › Security › Account isolation makes the separation stronger: a private view of the filesystem,
a private
/tmpper account, other accounts' processes hidden, and SFTP-only access. Check first shows what a change would do on every server before you apply it. See Account isolation. - Packages can enforce CPU, memory and process limits, so one busy or hacked website can't slow down the others.
The panel does not run as root
The panels, HF Mail, HF Files, HF Studio and the API are one program, hf-api. It runs as the unprivileged user
hostfog and listens on a local socket behind Nginx; it is never reachable directly from the internet.
Anything that needs root (creating users, writing web server and mail settings, issuing certificates) goes through one helper, hf-agent:
hostfogmay run onlyhf-agentas root (one line in/etc/sudoers.d/hostfog), and nothing else.- Every argument hf-agent receives is checked against a strict pattern before it is used: usernames, domains, database names, email addresses, paths inside a home folder, IP addresses, numbers. Anything else is refused.
- Passwords, keys and file contents reach hf-agent on its standard input, never as arguments, so they never show in the server's process list.
- Commands that change settings wait for each other, so two requests never edit the same file at once.
See Server layout for the files and services involved.
Signed releases and updates
Every release has a MANIFEST that lists each file with its SHA-256 checksum, signed with the publisher's ed25519
release key. The installer and every update check that signature and every checksum before anything runs; a
release that has been changed, or that holds files not in the manifest, is refused. See
Updating.
Sign-in
| Protection | What it does |
|---|---|
| Passwords | stored only as bcrypt hashes. A wrong username takes as long to refuse as a wrong password, so sign-in does not tell which usernames exist. |
| Two-factor login | a 6-digit code from an authenticator app; each code works once. Backup codes cover a lost phone. Administrators can require it for all staff. |
| Passkeys | sign in with Face ID, Touch ID, Windows Hello, a phone or a security key. They can't be phished and count as two-factor login. |
| Lock-out per address | 8 failed sign-in steps from one IP address (one /64 for IPv6) in 15 minutes block that address for up to 15 minutes. |
| Wait per login | after 5 wrong passwords or codes for one login in an hour, each further try must wait: 15 seconds, doubling each time, up to 15 minutes. |
| New device email | the login's owner gets an email when someone signs in from a new address. |
| Activity log | every sign-in and every change is recorded with who made it and from which IP address. See Activity log. |
HF Files and HF Studio use the same limits, and HF Mail, the web disk and share links with a password limit wrong passwords too.
Sessions and CSRF
- The session cookie is
HttpOnly,SecureandSameSite=Strict, and its id changes at every sign-in. - A session ends after 60 minutes without activity.
- Changing a password signs out every other session of that login.
- Every change needs the session's CSRF token in a request header, compared in constant time; a request from another
site (another
Origin) is refused before any screen runs. - Log in as works only while the staff member is still allowed to manage that account: it ends as soon as they are suspended, change their password, or lose the account.
- Read-only administrator logins can look at everything but can't change anything.
API tokens
- A token is
hf_followed by 48 random hexadecimal characters. HF Panel keeps only its SHA-256 hash, so a token can't be read back from the panel database. - A token acts as the person who made it, with Read only or Read & change access, and can be limited to Allowed IPs.
- Missing or wrong tokens count towards the same lock-out as wrong passwords.
- The API has its own address on port 2087 and answers programs only.
See API overview.
Secrets and outgoing connections
- Saved passwords and tokens for backup destinations and other services are sealed with the server's own key,
/etc/hostfog/secrets.key, which only root and hf-api can read. - The settings file
/etc/hostfog/config.jsonis readable only by root and hf-api. - Uptime checks, webhooks and other addresses the panel fetches for you refuse private and reserved network addresses (also when a domain name points to one), unless an administrator allows them.