CVE-2026-57232 is a low-severity (CVSS 3.1) Server-Side Request Forgery (SSRF) vulnerability in contao/contao. A fix is available for contao/contao — see the affected versions and patch details below.
Contao: Server-Side Request Forgery (SSRF) via Unvalidated RSS Feed URL in Feed Reader Module
Exploitation Status
No confirmed exploitation observed yet
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-57232.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
CVE-2026-57232 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 394,415 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
contao/contao🐘contao/contao🐘contao/core-bundle🐘contao/core-bundleReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.
Description
Summary
The Feed Reader front-end module passes RSS feed URLs from its configuration directly to $this->feedIo->read($url) without any scheme validation or private-IP blocklist. A backend user with module-edit permissions can configure an arbitrary URL pointing to internal network services, cloud-provider metadata endpoints, or loopback addresses, causing the server to fetch those resources unconditionally. Confirmed live: the server successfully reaches the internal MySQL database container and its own loopback Apache instance.
Details
In core-bundle/src/Controller/FrontendModule/FeedReaderController.php, the getResponse() function iterates over the configured feed URLs and passes each one directly to the HTTP client with no validation:
// Line 50-55
foreach (StringUtil::trimsplit('[\n\t ]', trim($model->rss_feed)) as $url) {
try {
$feed = $this->cache->get(
'feed_reader_'.$model->id.'_'.md5($url),
function (ItemInterface $item) use ($url, $model) {
$readerResult = $this->feedIo->read($url, new Feed()); // <-- no validation
The DCA field definition for rss_feed in tl_module.php carries no URL scheme or host validation:
'eval' => array('mandatory'=>true, 'decodeEntities'=>true, 'style'=>'height:60px')
The HTTP client is wired as @psr18.http_client (Symfony HttpClient) with no SSRF protection configured (NoPrivateNetworkHttpClient is not used).
Impact
This is a CWE-918 (SSRF) vulnerability. A backend user with module-edit access can:
- Enumerate internal network services -- probe any IP/port on the internal network by observing response times and error messages
- Reach internal APIs -- access unauthenticated services inside the Docker/Kubernetes network (databases, caches, admin panels)
- Steal cloud metadata credentials -- on AWS, fetch
http://169.254.169.254/latest/meta-data/iam/security-credentials/to obtain IAM role credentials (IMDSv1 has no authentication) - Pivot to internal infrastructure -- use the server as a proxy to interact with services not exposed to the public internet
Confirmed in live testing: the server successfully connected to the internal MySQL container (172.19.0.3:3306) and retrieved a full HTTP response from its own loopback interface (127.0.0.1:80).
Remediation
-
Use
NoPrivateNetworkHttpClient-- wrap the injected HTTP client with Symfony's built-in SSRF protection before passing it to feedIo:use Symfony\Component\HttpClient\NoPrivateNetworkHttpClient; $safeClient = new NoPrivateNetworkHttpClient($this->httpClient);This blocks all RFC-1918, loopback, and link-local addresses at the HTTP client level.
-
Validate URL scheme and host -- before calling
feedIo->read(), parse the URL and reject anything that is nothttp://orhttps://with a public routable IP or hostname. -
Configure the DCA field -- add
'rgxp' => 'url'and a custom validation callback totl_module.rss_feedto reject non-public URLs at save time.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐘Packagist | contao/contao | ≥ 5.3.35&&< 5.3.48 | 5.3.48composer require contao/contao:^5.3.48 |
| 🐘Packagist | contao/contao | ≥ 5.4.0&&< 5.7.9 | 5.7.9composer require contao/contao:^5.7.9 |
| 🐘Packagist | contao/core-bundle | ≥ 5.3.35&&< 5.3.48 | 5.3.48composer require contao/core-bundle:^5.3.48 |
| 🐘Packagist | contao/core-bundle | ≥ 5.4.0&&< 5.7.9 | 5.7.9composer require contao/core-bundle:^5.7.9 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for contao/contao, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update contao/contao to 5.3.48 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-57232 is resolved across your whole dependency graph.
Workarounds
Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.
Frequently Asked Questions
Is CVE-2026-57232 in your dependencies?
Find it across Packagist, including transitive dependencies.