Skip to content
Api Admin Rce.md

Api Admin Rce.md

github.com • October 5, 2026

The admin file-upload endpoint POST /admin/Index/upload in ApiAdmin (ThinkPHP 6-based API management platform) takes the uploaded file's extension verbatim — there is no whitelist, blacklist or content check — and move_uploaded_file() drops the file into the web-accessible directory public/upload/Ymd/ . Any logged-in admin user can upload a .php file and reach it directly over HTTP, achieving remote code execution on the server.

ApiAdmin <= 5.0 (ThinkPHP 6.0, config/apiadmin.php APP_VERSION = 5.0; last release 2020)

Any back-end account with admin panel access

Response ( apiAuth is the token carried as Api-Auth header on all later requests):

Step 2 — Upload a PHP shell

Response — the server returns the full URL of the stored file (extension .php preserved, name randomized):

Step 3 — Execute the shell

The uploaded PHP file is executed by the server — RCE confirmed. The attacker can then drop any PHP backdoor (webshell) the same way.

app/controller/admin/Index.php:11-50 — the extension is extracted from the client-supplied filename with no validation, and the file is moved into the web root:

The vulnerability is Index.php:36-38 + :42 :

Index.php:37 — array_pop() keeps whatever extension the attacker sends ( .php , .phtml , .php5 …); there is no in_array() extension check and no getimagesize() content check;

Index.php:42 — move_uploaded_file() stores it under $_SERVER['DOCUMENT_ROOT'] (= public/ ), which is directly web-served, so the file is both readable and executed as PHP.

The only hardening is a random filename ( md5(time().uniqid()) ), which does not prevent access — the fileUrl is returned to the attacker in the same response.

Extracted Entities

Attack Types (1)

MITRE ATT&CK (1)

Platforms (2)

Tools (1)