Feb 19, 2026·7 min read·4 visits
Restricted TYPO3 backend users can create redirects for *any* domain on the instance, bypassing site-specific permissions. This allows an editor of 'Site A' to redirect traffic from 'Site B' to a malicious target.
A Broken Access Control vulnerability in the TYPO3 CMS 'Redirects' module allows restricted backend users to manipulate redirect rules for domains they are not authorized to manage. By exploiting this flaw, a low-privileged editor with access to the module can hijack traffic from any site hosted on the same TYPO3 instance, facilitating high-impact phishing or SEO poisoning attacks.
Multi-tenancy is the bread and butter of enterprise CMS installations. You have one TYPO3 instance hosting the corporate site, the HR portal, the marketing blog, and maybe a few localized landing pages. The security model relies heavily on 'Web Mounts'—invisible fences that keep the HR intern from accidentally nuking the CEO's blog post. It’s a beautiful system, usually.
But here’s the thing about complex systems: eventually, someone adds a feature that decides it's too cool for fences. Enter the Redirects Module. This component is responsible for handling HTTP redirects (301s, 307s) directly within the CMS. Ideally, if I'm an editor for blog.example.com, I should only be able to tell blog.example.com/old-post to go to blog.example.com/new-post.
CVE-2025-59021 reveals that TYPO3 forgot to check the badge at the door. The Redirects module treated permissions with a binary simplicity: 'Do you have access to the module?' If the answer was yes, the system handed you the keys to the entire kingdom's traffic control tower. This isn't just a bug; it's the digital equivalent of giving a valet driver the keys to every car in the parking lot, not just the one they were hired to park.
The vulnerability is a classic case of Missing Authorization (CWE-862), specifically manifesting as an Insecure Direct Object Reference (IDOR) on steriods. In TYPO3, permissions are granular. You have table-level permissions (can I edit sys_redirect rows?) and page-tree permissions (can I edit pages under node/123?).
However, redirect records in the sys_redirect table are technically detached from the standard page tree hierarchy. They are records that apply to a domain, but they don't necessarily live under that domain's page ID in a way that inherits the standard permission checks automatically. The code responsible for saving these records checked if the user had write access to the table, but it failed to cross-reference the source_host field of the redirect against the user's allowed Web Mounts.
> [!NOTE]
> In a multi-site setup, this is catastrophic. A user restricted to marketing.local could create a rule saying: "If a request comes in for secure-admin.local/login, redirect it to attacker-controlled-site.com/fake-login."
The application logic implicitly trusted that if a user could see the form, they were allowed to modify whatever data they put into it. It’s a failure to validate the semantic validity of the input (the domain ownership) against the user's contextual privileges.
The fix required a significant overhaul of how redirect permissions are calculated. The core team couldn't just add a simple if statement; they had to introduce an entirely new service to map users to hosts.
First, they introduced the SourceHostProvider. This service intersects the site configurations with the user's web mounts to determine exactly which domains a user is legally allowed to touch. Then, they implemented a RedirectPermissionGuard. Here is a simplified look at the logic flow:
Before (Vulnerable Logic):
// DataHandler.php
public function processDatamap() {
if ($user->check('tables_modify', 'sys_redirect')) {
// User can write to the table? Great, save it.
$this->saveRecord($table, $id, $data);
}
}After (Patched Logic):
The patch introduces a hook into the DataHandler to inspect the payload before saving.
// DataHandlerPermissionGuardHook.php
public function processDatamap_preProcessFieldArray(array $incomingFieldArray, ...): void
{
// 1. Get the source_host the user is trying to set
$requestedHost = $incomingFieldArray['source_host'];
// 2. Ask the SourceHostProvider if the user owns this host
if (!$this->sourceHostProvider->isHostAllowed($user, $requestedHost)) {
// 3. Yeet the request into the void
$this->logger->warning('Attempt to modify sys_redirect for unauthorized host');
throw new AccessDeniedException('You have no power here.');
}
}They didn't just stop at the UI (which can be bypassed). They hooked directly into the data persistence layer (DataHandler), ensuring that even if you craft a raw HTTP POST request bypassing the backend interface, the database execution will still be blocked.
Let's walk through how a malicious insider—or an attacker who has compromised a low-level editor account—would weaponize this. We assume the attacker has access to the TYPO3 backend and the Redirects module, but is restricted to a minor microsite.
The Setup:
http://useless-microsite.corphttp://intranet.corpThe Attack Chain:
intranet.corp (The vulnerability allows selecting/entering this manually)./hr/payroll-loginhttps://evil-payroll-clone.comintranet.corp, the record is written to sys_redirect.intranet.corp/hr/payroll-login, the TYPO3 routing engine sees the match and immediately bounces them to the phishing site.This is a Medium severity CVSS (6.4), but don't let the score fool you. In the hands of a creative attacker, the impact is high. The primary issue is Scope Change (S:C). The vulnerability allows lateral movement from a low-value asset (a microsite) to a high-value asset (the main corporate domain).
Scenarios:
/ redirects to /) effectively taking the main site offline for all visitors.Because this requires authentication, it's not a "drive-by" exploit. However, in large organizations with hundreds of CMS users, the "Insider Threat" or "Compromised Credential" vector is statistically probable.
The remediation is straightforward: Update TYPO3. The patch is available across all supported versions (v10 through v14). Specifically, you are looking for versions 14.0.2, 13.4.23, 12.4.41, 11.5.49, or 10.4.55.
If you cannot patch immediately: You must restrict access to the Redirects module. Go to your Backend User Groups and uncheck the "Redirects" module for everyone except the absolute highest-tier Super Admins who are trusted with the entire installation.
Also, review your current sys_redirect table. Run a SQL query to audit for suspicious cross-domain redirects:
SELECT * FROM sys_redirect
WHERE source_host NOT IN ('your-primary-domain.com')
ORDER BY crdate DESC;If you see redirects for domains created by users who shouldn't be managing those domains, you may have already been targeted.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
TYPO3 CMS TYPO3 Association | 14.0.0 - 14.0.1 | 14.0.2 |
TYPO3 CMS TYPO3 Association | 13.0.0 - 13.4.22 | 13.4.23 |
TYPO3 CMS TYPO3 Association | 12.0.0 - 12.4.40 | 12.4.41 |
TYPO3 CMS TYPO3 Association | 11.0.0 - 11.5.48 | 11.5.49 |
TYPO3 CMS TYPO3 Association | 10.0.0 - 10.4.54 | 10.4.55 |
| Attribute | Detail |
|---|---|
| CWE | CWE-862 (Missing Authorization) |
| Attack Vector | Network (Authenticated) |
| CVSS v3.1 | 6.4 (Medium) |
| Impact | Traffic Hijacking, Phishing, SEO Poisoning |
| Constraint | Requires Backend User Account |
| Fix Type | Patch (Logic Update) |
The software does not perform an authorization check when an actor attempts to access a resource or perform an action.