zum Inhalt springen

Server-side request forgery vulnerability in webhook functionality of TYPO3 allows attackers to access systems that would otherwise be inaccessible

Open Source

NTCF:
NTCF-2025-3379

CVE:
CVE-2025-47936

Product:
TYPO3

Vendor:
TYPO3

Criticality:
low

Status:
fixed

Discovered:
2025-02-06

Detail:
Public

Vulnerable version:
12.0.0-12.4.30, 13.0.0-13.4.11

Fixed version:
12.4.31, 13.4.12

Summary

TYPO3 is an enterprise Content Management System (CMS) developed in PHP. It has been discovered that the versions 12.0.0-12.4.30 and 13.0.0-13.4.11 are susceptible to server side request forgery.

While this is not a vulnerability in TYPO3 itself, it may enable attackers to blindly access systems that would otherwise be inaccessible.
To prevent this behavior, manual actions are required by defining a list of allowed hosts.

Background

TYPO3 is a widely used open source enterprise CMS known for its extensibility and customizability. It allows organizations to build and manage complex websites while offering a range of extensions that enhance its functionality. Various authorities at the national, cantonal and municipality level use TYPO3 - often in contexts where confidentiality, availability and integrity are essential. 

In a pilot project with the NCSC, the NTC evaluated the security of TYPO3 and its extensions to ensure the security of open source software used within the Swiss administration. Read more about the project here.

Vulnerability

The webhook functionality in TYPO3 allows admin users to call other hosts, for example to trigger a text alert when a new page is added. Webhooks can often be used for Server-Side Request Forgery (SSRF) to call internal services that are otherwise inaccessible from outside of the network.

The code used to send HTTP requests for webhooks did not have a check for the hostname and therefore allowed requests to any hosts. Below the code as of 1b6139d694418f53a9fd0833b24d0b5ed43a08f9. The business logic does not filter requests and uses an HTTP client make request:

public function request(string $uri, string $method = 'GET', array $options = [], ?string $context = null): ResponseInterface { return $this->guzzleFactory->getClient()->request($method, $uri, $options); }
The client found in typo3/sysext/core/Classes/Http/Client/GuzzleClientFactory.php handles TLS verification options and sets up custom middlewares that are configured globally. No check for allowed hostnames is present:
/** * Creates the client to do requests */ public function getClient(): ClientInterface { $httpOptions = $GLOBALS['TYPO3_CONF_VARS']['HTTP']; $httpOptions['verify'] = filter_var($httpOptions['verify'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? $httpOptions['verify']; if (isset($GLOBALS['TYPO3_CONF_VARS']['HTTP']['handler']) && is_array($GLOBALS['TYPO3_CONF_VARS']['HTTP']['handler'])) { $stack = HandlerStack::create(); foreach ($GLOBALS['TYPO3_CONF_VARS']['HTTP']['handler'] ?? [] as $name => $handler) { $stack->push($handler, (string)$name); } $httpOptions['handler'] = $stack; } return new Client($httpOptions); }

Proof of Concept

Webhooks can be created in the backend under System > Webhooks.

After adding an internal service as the endpoint and triggering the webhook - for example by creating a new page - the internal service gets called by the TYPO3 application.

Webhook in TYPO3 allows access to internal APIs

In practice, the impact of this vulnerability is reduced as the SSRF is blind. The response of the downstream server is not shown to the user.

Remediation

The vulnerability was addressed in change number 89466, where an additional validation middleware was introduced.

Patches and Manual Actions

Users are encouraged to update to TYPO3 versions 12.4.31 LTS, 13.4.12 LTS that allow site operators to define the hosts that webhooks can connect to.

This can be achieved by configuring the allowlist in $GLOBALS['TYPO3_CONF_VARS']['HTTP']['allowed_hosts']['webhooks'].

  • If the allowlist is not defined or set to null, all requests will be allowed.
  • If the allowlist is an empty array, all requests will be blocked.

By default, the factory setting allows all requests. This prevents existing webhooks from failing after upgrading to the affected TYPO3 versions.

Timeline

2025-02-06: initial discovery

2025-02-21: private disclosure to vendor

2025-05-20: fix by vendor

2025-10-13: public disclosure