Kai Ole Hartwig
9 min read
Low
By

TYPO3 on Kubernetes under IT-Grundschutz, part 13: Hardening TYPO3 itself

For twelve parts, this series was about the platform. Most attacks on a TYPO3 website, however, do not target the cluster. They target the backend, extensions and forms. A perfectly hardened Kubernetes helps little if the backend is openly reachable on the internet.

This part shows how TYPO3 itself is secured as a web application under APP.3.1. It covers access to the backend, permissions and approvals, a web application firewall in front of it, and updates as a fixed routine.

Part 13 of 14 of the series "TYPO3 on Kubernetes under IT-Grundschutz". The overview of all parts is in part 1.

01 — Access to the backend

The backend is the most valuable door of a TYPO3 installation. Whoever gets in can change content, upload files and create users. APP.3.1.A1 therefore requires appropriate authentication and limits for failed sign-in attempts.

Enforcing multi-factor authentication

TYPO3 ships TOTP and recovery codes in the core. BE.requireMfa makes the second factor mandatory. The value 1 applies to all users, the value 3 only to administrators. With a high protection need, 1 is the honest choice. An editor account can cause considerable damage too.

 

// config/system/additional.php
$GLOBALS['TYPO3_CONF_VARS']['BE']['requireMfa'] = 1;
$GLOBALS['TYPO3_CONF_VARS']['BE']['loginRateLimit'] = 5;
$GLOBALS['TYPO3_CONF_VARS']['BE']['loginRateLimitInterval'] = '15 minutes';
$GLOBALS['TYPO3_CONF_VARS']['BE']['sessionTimeout'] = 3600;
$GLOBALS['TYPO3_CONF_VARS']['BE']['cookieSameSite'] = 'strict';

 

The pair of limits caps failed sign-in attempts per address. Both values are the core defaults. What matters is that nobody loosens them. The session ends after one hour without activity instead of the default eight hours.

Signing in through the identity provider

Even better is a backend that manages no passwords of its own. Signing in via OAuth2 or OpenID Connect moves password, MFA and account lockout to the central identity provider. Whoever leaves the organisation loses backend access together with the account.

A typical pitfall in TYPO3 14: some extensions still build the callback URL on /typo3/index.php. That entry point no longer exists. Sign-in then goes nowhere, often without a clear error message. A test of the complete sign-in path therefore belongs to every update.

Narrowing the path to the backend

The backend does not need to be reachable from everywhere. BE.IPmaskList only admits requests from defined networks. Alternatively, the reverse proxy blocks the backend path for all other addresses. With BE.entryPoint, the backend can also run on a host of its own. Access rules, certificates and limits for editors and visitors can then be managed separately.

02 — Permissions, approvals and the install tool

Most editor accounts need no administrator rights. Backend groups with exactly the tables, fields and page trees of a role limit the damage of a compromised account. System maintainers, meaning accounts with access to the system settings, should be countable on one hand.

Custom backend modules deserve a second look. TYPO3 14 only accepts certain values for module access. An outdated entry silently locks the module for everyone, administrators included. That is safe, but only shows up once somebody needs the module.

Four eyes with workspaces

Workspaces separate editing from publishing. Changes land in a draft first, and a second person approves them. That protects the integrity of the content. As a side effect, it creates a record of who approved what and when.

The same principle applies to AI agents that access TYPO3 via MCP. They sign in per person via OAuth, not with a shared key. They only write to the workspace. They may only publish if that has been explicitly enabled. Every change thus stays attributable to a human.

The install tool stays closed

In operation, the install tool is not needed. If BE.installToolPassword is empty, TYPO3 refuses access entirely. Only system maintainers see the admin tools in the backend. Maintenance tasks such as database updates run via the console during deployment, as described in part 8.

03 — A web application firewall in front of TYPO3

For an increased protection need, APP.3.1.A20 calls for a web application firewall. In a cluster it sits best in the tenant's reverse proxy. There it sees every request before PHP processes it.

Limits that slow down abuse

Rate limits per client implement the limits from APP.3.1.A1 and A7 before a request even reaches TYPO3. In Caddy this works with the rate-limit module:

 

@login path /typo3/login
rate_limit @login {
    zone backend_login {
        key    {client_ip}
        events 5
        window 60s
    }
}

 

Three zones of different strictness have proven themselves. Sign-in gets few attempts per minute. The backend gets more room, because editors generate many requests. The frontend gets enough that feeds, search engines and legitimate crawlers do not suffer. A7 explicitly asks for exactly this trade-off.

The real client IP

Behind an ingress, the proxy initially only sees the ingress address. All visitors then count as a single client. The first rate-limit rule locks out the whole website, often including your own editors. The fix is trusted_proxies for the pod network. Only then does the proxy take the real address from X-Forwarded-For, and only from there.

Behaviour instead of signatures

CrowdSec complements the limits. It evaluates the access logs, recognises patterns such as scans or brute force, and blocks the source. The proxy answers obvious scanner paths such as wp-login.php directly with a 404, without starting PHP. It rejects HTTP methods that are not needed. A cache PURGE is only allowed from the internal network.

One quirk is worth knowing. If the connection between proxy and CrowdSec silently hangs, the proxy lets everything through or nothing, depending on configuration. Without a dedicated check, both surface late. An alert on the bouncer's state makes the failure visible. A liveness probe would be wrong here: if CrowdSec failed, every proxy pod would restart at once. After every major TYPO3 update, the rules also need a review, as A20 requires.

04 — Headers, error pages and updates

HTTP headers under APP.3.1.A21

The module names the headers explicitly: Content-Security-Policy, Strict-Transport-Security, Content-Type, X-Content-Type-Options and Cache-Control. The proxy sets most of them the same way for all tenants. The Content-Security-Policy, by contrast, only the application itself knows. TYPO3 ships its own API for it. Per site, a csp.yaml describes which sources are allowed. The feature security.frontend.enforceContentSecurityPolicy enforces the policy in the frontend.

Cookies belong here too. A21 asks for secure, httponly and SameSite. TYPO3 sets the backend cookie with SameSite=strict by default. Cookies from extensions deserve the same check.

Revealing neither product nor version

APP.3.2.A12 asks for responses without product name and version number. The proxy removes the Server header, and the generator meta tag names no version. Error pages only show a generic message with a unique identifier. TYPO3 delivers exactly that: a short error page with a request ID. With that ID, operations finds the error in the central log from part 11. Visitors see no details as long as SYS.displayErrors is set to 0 in production.

Updates as a fixed routine

The TYPO3 security advisories are published in bundles and announced in advance. Whoever subscribes to them and uses the CVE gate from part 4 knows the same day whether an installation is affected. Extensions deserve particular attention, because not every one is maintained as well as the core. Unused extensions get removed. Code that is not installed has no vulnerabilities. Once a year and after major changes, a penetration test comes on top, as APP.3.1.A22 foresees.

How it maps to IT-Grundschutz

Frequently asked questions

Is the multi-factor authentication in the TYPO3 core enough?+

For most installations, yes. TOTP and recovery codes are part of the core and can be enforced with BE.requireMfa. If you already run a central identity provider, it is better to move sign-in there. TYPO3 then follows the same rules as every other system.

Don't rate limits slow down search engines and feeds as well?+

Only if the limits are too tight. The frontend needs more generous values than sign-in. APP.3.1.A7 explicitly asks to take functions meant for automated use, such as RSS feeds, into account. The access logs quickly show whether legitimate clients hit a limit.

Why a WAF if TYPO3 itself is carefully developed?+

Because not every extension is maintained as well as the core. The WAF catches known attack patterns and scans before they reach PHP. It does not replace updates. It does buy time between a vulnerability becoming known and the patch.

How often should a TYPO3 website be tested?+

APP.3.1.A22 requires regular reviews without prescribing a fixed interval. A penetration test once a year and after major changes has proven itself. Automated scans in the pipeline come on top. The results are documented and presented to the information security officer.

Conclusion

The platform protects TYPO3, but it does not replace protecting the application itself. MFA and an identity provider secure the backend. Roles and workspaces restrict every account, including that of an AI agent. A WAF with limits catches abuse before PHP starts. Headers, error pages and a fixed update routine close what is left. That makes the requirements of APP.3.1 verifiable, up to the WAF for a high protection need.

Continue with part 14: The reference chart, which brings every building block of the series together in an open Helm chart. The overview of all parts and how they map to the Grundschutz modules is in part 1: which modules actually apply. Back to part 12: Availability with a high protection need.

I harden your TYPO3 as a web application. From backend access to the WAF in front of it.

MFA or sign-in through your identity provider, roles and workspaces, limits and a WAF in the proxy, secure headers and an update routine that takes effect the same day.

Platform operations rather than advice on paper: if you want, I run your TYPO3 for you on an ongoing basis and deliver the evidence for your audit.

Book a call →

About the author

Photo of Kai Ole Hartwig.

Kai Ole Hartwig

Freelance DevSecOps consultant · OnlyOle Consulting

Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.