GHSA-6j68-gcc3-mq73: Admidio Vulnerable to SSRF and Local File Read via Unrestricted URL Fetch in SSO Metadata Endpoint
SummaryThe SSO metadata fetch endpoint at `modules/sso/fetch_metadata.php` accepts an arbitrary URL via `$_GET['url']`, validates it only with PHP's `FILTER_VALIDATE_URL`, and passes it directly to `file_get_contents()`. `FILTER_VALIDATE_URL` accepts `file://`, `http://`, `ftp://`, `data://`, and `php://` scheme URIs. An authenticated administrator can use this endpoint to read arbitrary local files via the `file://` wrapper (Local File Read), reach internal services via `http://` (SSRF), or fetch cloud instance metadata. The full response body is returned verbatim to the caller.DetailsVulnerable CodeFile: `D:/bugcrowd/admidio/repo/modules/sso/fetch_metadata.php`, lines 9-34FILTER_VALIDATE_URL Does Not Block Dangerous SchemesPHP's `FILTER_VALIDATE_URL` is a format validator, not a security allowlist. It accepts any syntactically valid URL regardless of scheme or destination. The following schemes all pass validation and are handled by `file_get_contents()`:| Scheme | Impact |
|--------|--------|
| `file:///etc/passwd` | Read any local file the web server process can access |
| `http://127.0.0.1/` | SSRF to localhost services (databases, admin panels, internal APIs) |
| `http://169.254.169.254/latest/meta-data/` | AWS EC2 instance metadata (IAM credentials) |
| `data://text/plain,payload` | Data URI content injection |Confirmed by testing PHP's filter_var() and file_get_contents() with all of the above:file:// Does Not Require allow_url_fopenPHP's `file://` stream wrapper is the native filesystem handler and is always available regardless of the `allow_url_fopen` INI setting. The Local File Read vector works even on configurations that disable HTTP URL fetching.Response Is Returned VerbatimThe fetched content is echoed directly at line 34 (`echo $metadata`), making the complete contents of any readable local file or internal service response available to the caller.PoC**Prerequisites:** Administrator account session cookie and CSRF token.**Step 1: Read the Admidio database configuration file**Expected response: Full contents of config.php including the database host, username, and password in plaintext.**Step 2: Read system password file****Step 3: SSRF to AWS EC2 instance metadata (when deployed on AWS)**Expected response: IAM role name followed by temporary AWS access key and secret.**Step 4: SSRF to an internal service on localhost**(Probes a Redis instance on localhost.)Impact**Local File Read:** The attacker can read any file accessible to the PHP web server process, including Admidio's `config.php` (database credentials), `/etc/passwd`, private keys stored in the web root, and `.env` files.**Database Credential Theft:** Reading `config.php` exposes the database password. An attacker with the database password can access all member data, extract password hashes, and modify records directly, bypassing all application-level access controls.**Cloud Metadata Exposure:** On AWS, GCP, or Azure deployments, fetching the instance metadata endpoint exposes IAM role credentials with potentially broad cloud-level access.**Internal Network Reconnaissance:** The endpoint can probe internal services (Redis, Elasticsearch, internal admin panels) that are not externally accessible.**Scope Change:** Impact escapes the Admidio application boundary, reaching the underlying server filesystem and internal network, justifying the S:C score.Recommended FixFix 1: Restrict to HTTPS scheme and block internal IP rangesFix 2: Use cURL with explicit scheme restrictionNote: DNS rebinding protections should also be considered; resolving the hostname before the request and blocking the request if it resolves to a private IP provides defense-in-depth.
CVSS v3.1: 6.8