{"id":"CVE-2026-57232","aliases":["GHSA-87mg-5grr-rhwh"],"url":"https://o3.security/vulnerability/CVE-2026-57232","summary":"Contao: Server-Side Request Forgery (SSRF) via Unvalidated RSS Feed URL in Feed Reader Module","details":"### Summary\n\nThe 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.\n\n---\n\n### Details\n\nIn `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:\n\n```php\n// Line 50-55\nforeach (StringUtil::trimsplit('[\\n\\t ]', trim($model->rss_feed)) as $url) {\n    try {\n        $feed = $this->cache->get(\n            'feed_reader_'.$model->id.'_'.md5($url),\n            function (ItemInterface $item) use ($url, $model) {\n                $readerResult = $this->feedIo->read($url, new Feed()); // <-- no validation\n```\n\nThe DCA field definition for `rss_feed` in `tl_module.php` carries no URL scheme or host validation:\n```php\n'eval' => array('mandatory'=>true, 'decodeEntities'=>true, 'style'=>'height:60px')\n```\n\nThe HTTP client is wired as `@psr18.http_client` (Symfony HttpClient) with no SSRF protection configured (`NoPrivateNetworkHttpClient` is not used).\n\n---\n\n### Impact\n\nThis is a CWE-918 (SSRF) vulnerability. A backend user with module-edit access can:\n\n1. **Enumerate internal network services** -- probe any IP/port on the internal network by observing response times and error messages\n2. **Reach internal APIs** -- access unauthenticated services inside the Docker/Kubernetes network (databases, caches, admin panels)\n3. **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)\n4. **Pivot to internal infrastructure** -- use the server as a proxy to interact with services not exposed to the public internet\n\nConfirmed 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`).\n\n---\n\n### Remediation\n\n1. **Use `NoPrivateNetworkHttpClient`** -- wrap the injected HTTP client with Symfony's built-in SSRF protection before passing it to feedIo:\n   ```php\n   use Symfony\\Component\\HttpClient\\NoPrivateNetworkHttpClient;\n\n   $safeClient = new NoPrivateNetworkHttpClient($this->httpClient);\n   ```\n   This blocks all RFC-1918, loopback, and link-local addresses at the HTTP client level.\n\n2. **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.\n\n3. **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.","published":"2026-07-31T18:29:53.924Z","modified":"2026-10-21T02:58:44.793868109Z","cvss":{"score":3.1,"severity":"LOW","vector":"CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N"},"epss":{"score":0.00182,"percentile":0.07768,"asOf":"2026-08-24"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"Packagist","name":"contao/contao","fixedVersion":"5.3.48"},{"ecosystem":"Packagist","name":"contao/contao","fixedVersion":"5.7.9"},{"ecosystem":"Packagist","name":"contao/core-bundle","fixedVersion":"5.3.48"},{"ecosystem":"Packagist","name":"contao/core-bundle","fixedVersion":"5.7.9"}],"fix":{"url":"https://github.com/contao/contao/commit/27f6201809553bee767dcef15535bb8f0f4eac5f","label":"contao/contao@27f6201"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/57xxx/CVE-2026-57232.json"},{"type":"ADVISORY","url":"https://github.com/contao/contao/security/advisories/GHSA-87mg-5grr-rhwh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-57232"},{"type":"FIX","url":"https://github.com/contao/contao/commit/27f6201809553bee767dcef15535bb8f0f4eac5f"},{"type":"FIX","url":"https://github.com/contao/contao/commit/53b939ff2c4718e3a1d7c54ddd8886e9370618e4"},{"type":"WEB","url":"https://contao.org/en/security-advisories/server-side-request-forgery-via-unvalidated-rss-feed-urls"},{"type":"WEB","url":"https://github.com/FriendsOfPHP/security-advisories/blob/master/contao/contao/CVE-2026-57232.yaml"},{"type":"WEB","url":"https://github.com/FriendsOfPHP/security-advisories/blob/master/contao/core-bundle/CVE-2026-57232.yaml"},{"type":"PACKAGE","url":"https://github.com/contao/contao"},{"type":"WEB","url":"https://github.com/contao/contao/releases/tag/5.3.48"},{"type":"WEB","url":"https://github.com/contao/contao/releases/tag/5.7.9"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-21T02:58:44.793868109Z"}}