
Proof-of-concept demonstrating an authenticated blind SSRF in Matomo's SiteContentDetector, allowing internal network reconnaissance and requests to internal services via crafted site URLs.
Name: CYBER-SEC
Contact: [email protected]
Matomo allows an authenticated site administrator to configure a site's main_url with an internal address. Any authenticated user with view access can later trigger getTrackingMethodsForSite, causing the server to perform a blind HTTP request to the configured URL.
The destination is validated only with hostname-based protections and does not properly reject loopback, RFC1918, or link-local addresses after resolution. As a result, the application can be abused to perform blind server-side requests to internal services.
Product: Matomo
Affected version: 5.11.2 verified
Component: SiteContentDetector / SitesManager
Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N
Base Score: 5.8 Medium
enable_internet_features must be enabled.main_url.The issue involves the following flow:
Source:
SitesManager.updateSite stores main_url after basic URL validation.
Trigger:
GET /index.php?module=SitesManager&action=getTrackingMethodsForSite&idSite=<id>
Sink:
SiteContentDetector::requestSiteResponse()
-> Http::sendHttpRequestBy()
The implementation does not properly reject internal destinations such as:
127.0.0.0/8
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
169.254.0.0/16
::1
fc00::/7
fe80::/10
Redirect targets should also be revalidated, because hostname-based filtering can be bypassed if the initial allowed hostname redirects to an internal address.
Use a listener you control in an authorized lab environment:
python3 -m http.server 8088
As an authenticated site administrator, configure the site's main_url to point to the controlled internal listener:
http://<controlled-internal-listener>:8088/ssrf-test
Do not test against third-party systems or cloud metadata endpoints unless you own and are authorized to test that environment.
As an authenticated user with view permission, trigger:
GET /index.php?module=SitesManager&action=getTrackingMethodsForSite&idSite=1
The controlled listener receives a server-side HTTP request from the Matomo server.
Example listener output:
GET /ssrf-test HTTP/1.1
Host: <controlled-internal-listener>:8088
User-Agent: Matomo
Matomo performs a server-side GET request to the configured main_url when getTrackingMethodsForSite is triggered.
This was verified using an internal loopback/internal HTTP listener that was not reachable externally, confirming blind SSRF behavior.
An authenticated attacker may abuse this behavior for:
Because the SSRF is blind, the attacker does not directly receive the HTTP response body through Matomo. However, request delivery alone can still be security-relevant in internal networks and cloud environments.
Recommended fixes:
Resolve the hostname to IP addresses before making the request.
Reject private, loopback, link-local, multicast, and otherwise unsafe IP ranges after DNS resolution.
Revalidate every redirect target before following redirects.
Prefer a strict allowlist of permitted outbound domains instead of hostname blocklists.
Apply SSRF protections consistently at the final HTTP request sink, not only during site URL configuration.
Consider restricting getTrackingMethodsForSite or the SiteContentDetector trigger to higher-privileged users.
Add audit logging for outbound server-side requests triggered by site configuration.
Verified against the official Matomo 5.11.2 Docker image without modifying source code.
This issue was reported by CYBER-SEC.