Skip to content

Contao: Server-Side Request Forgery (SSRF) via Unvalidated RSS Feed URL in Feed Reader Module

Low severity GitHub Reviewed Published Jul 13, 2026 in contao/contao • Updated Sep 24, 2026

Package

composer contao/contao (Composer)

Affected versions

>= 5.3.35, < 5.3.48
>= 5.4.0, < 5.7.9

Patched versions

5.3.48
5.7.9
composer contao/core-bundle (Composer)
>= 5.3.35, < 5.3.48
>= 5.4.0, < 5.7.9
5.3.48
5.7.9

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:

  1. Enumerate internal network services -- probe any IP/port on the internal network by observing response times and error messages
  2. Reach internal APIs -- access unauthenticated services inside the Docker/Kubernetes network (databases, caches, admin panels)
  3. 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)
  4. 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

  1. 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.

  2. Validate URL scheme and host -- before calling feedIo->read(), parse the URL and reject anything that is not http:// or https:// with a public routable IP or hostname.

  3. Configure the DCA field -- add 'rgxp' => 'url' and a custom validation callback to tl_module.rss_feed to reject non-public URLs at save time.

References

@leofeyer leofeyer published to contao/contao Jul 13, 2026
Published by the National Vulnerability Database Jul 31, 2026
Published to the GitHub Advisory Database Sep 24, 2026
Reviewed Sep 24, 2026
Last updated Sep 24, 2026

Severity

Low

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
High
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(20th percentile)

Weaknesses

Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Learn more on MITRE.

CVE ID

CVE-2026-57232

GHSA ID

GHSA-87mg-5grr-rhwh

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.