Docs: Security
Security
The security tilspire ships with: an enforced CSP, two-factor sign-in for every account, hardened sessions, and signed updates.
The security tilspire ships with, out of the box, on every install.
Content Security Policy #
tilspire ships with an enforcing Content Security Policy. Every script, stylesheet and font the admin panel needs is self-hosted, so the interface doesn't depend on a third-party CDN to load. The only external origins allowed by default are optional Google services you can turn on yourself in Settings — nothing is fetched from them unless you enable them.
Two-factor sign-in for every account #
Staff and members alike can turn on two-factor sign-in with any authenticator app, with recovery codes for a lost phone. The secret behind it is stored encrypted, under a key kept in your site configuration rather than the database, so a copy of the database alone doesn't reveal it. An administrator can reset another person's lost second factor after confirming their own password and code; the reset signs that account out everywhere and emails its owner.
Hardened sessions #
Session cookies are HttpOnly, SameSite, and marked Secure over HTTPS. Signing in issues a fresh session id, so a session token captured before sign-in can't be reused after it. Resetting a password, changing it, or changing the account's email address signs the account out everywhere else.
Since 1.14.0 the admin panel has its own sign-in inside your site session. It asks for your password and second factor even when you're signed in on the site, and asks again after a while without use — 30 minutes by default, set under System ▸ Settings ▸ Security. Making that longer asks for your password and code. See The admin panel.
Sessions are kept in site/sessions/, which tilspire refuses to serve. A host that backs up your web space would copy them too; to keep them elsewhere, set SESSION_SAVE_PATH in site/config/config.php to a folder outside it.
Passwords and sign-in #
One password policy applies everywhere a password is set, and a stored password hash is upgraded the next time its owner signs in. Failed sign-ins are throttled per address and per account, slowing down password guessing without letting a stranger lock you out.
Sign-ups #
Since 1.17.3 the sign-up form stops bots before an account exists. It carries a hidden field a person never sees, and checks that the form was neither sent back too quickly nor long after it was shown. Once you add reCAPTCHA keys under System ▸ Settings ▸ Security, Google's "I'm not a robot" box is checked on your server too. A refused sign-up gets one plain answer that doesn't say which check failed, and sign-ups are also limited per address.
A bot that gets through still never confirms its email address. tilspire removes member accounts left unconfirmed for a number of days, 7 by default: only ones that never signed in and have written nothing, and never staff. It is on for new sites; a site updated from an earlier release switches it on in the same place. Health shows whether both are in place.
Links in emails #
Links that confirm an email address or reset a password only open a page; nothing happens until you press its button. Mail systems that open every link to scan it can't use them on your behalf.
Roles and permissions #
Admin access is governed by roles and a permission catalogue, not a single all-or-nothing account level. Give an editor exactly the permissions they need, and nothing else. Nobody can manage an account whose role ranks above their own.
Prepared statements #
Every database query goes through parameterised, prepared statements. User input is never concatenated into SQL.
Content sanitisation #
Content saved through the editor is sanitised before it's stored, so pasted or injected markup can't carry scripts or unsafe attributes into your pages.
Protected files #
The .htaccess file tilspire ships with refuses requests for hidden files, configuration, backups, logs and archives, and the configuration file is written readable by its owner only. Behind nginx, mirror those rules in the server configuration, including one that refuses site/sessions/ and, since 1.15.0, site/drafts/, where images an agent proposed wait for review.
Signed updates #
Every update is checksummed and signature-verified before it's applied — see Updates.
The Operator API stays off #
The Operator API is off until an administrator turns it on. Its credentials expire, act only as the account that issued them, and propose changes that a person approves. Only the credential's owner can let it publish its own pages, posts and images for a while, from a short list of addresses, with every change undoable — see Operator API.
Backups you can trust #
Every update takes an encrypted snapshot of the database first. Off-site backups are encrypted before they leave your server, and each copy is proven by a nightly restore test.