Skip to content

CVE-2026-57518: Verified Reproduction

CVE-2026-57518: Pagekit CMS privilege escalation leading to RCE

CVE-2026-57518 is verified against pagekit/pagekit · github. Affected versions: <= 1.0.18. Fixed in None available; project archived. Vulnerability class: RCE. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00256.

REPRO-2026-00256 pagekit/pagekit · github RCE Jul 6, 2026 CVE entry .txt
Severity
HIGH
CVSS
8.8
Confidence
HIGH
Reproduced in
23m 15s
Tool calls
291
Spend
$6.60
01 · Overview

What Is CVE-2026-57518?

CVE-2026-57518 is a high-severity privilege escalation vulnerability in Pagekit CMS 1.0.18 and earlier that lets an authenticated low-privileged user escalate to admin-level permissions and ultimately achieve remote code execution. Pruva reproduced it (reproduction REPRO-2026-00256).

02 · Severity & CVSS

CVE-2026-57518 Severity & CVSS Score

CVE-2026-57518 is rated high severity, with a CVSS base score of 8.8 out of 10.

HIGH threat level
8.8 / 10 CVSS base
Weakness CWE-862 Missing Authorization / CWE-269 Improper Privilege Management — Missing Authorization

High — serious impact or readily exploitable. Prioritize remediation.

03 · Affected Versions

Affected pagekit/pagekit Versions

pagekit/pagekit · github versions <= 1.0.18 are affected.

How to Reproduce CVE-2026-57518

$ pruva-verify REPRO-2026-00256
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00256/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-57518

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

authenticated low-privileged user with 'user: manage users' permission self-assigns a custom role with 'system: manage packages' via POST /api/user/{id}, then uploads and installs a malicious PHP package

Attack chain
  1. POST /api/user/{id} with roles array containing custom role ID (not 3)
  2. POST /admin/system/package/upload
  3. POST /admin/system/package/install
  4. GET /packages/{name}/index.php?cmd=id
How the agent worked 707 events · 291 tool calls · 23 min
23 minDuration
291Tool calls
188Reasoning steps
707Events
2Dead-ends
Agent activity over 23 min
Support
20
Repro
477
Judge
18
Variant
188
0:0023:15

Root Cause and Exploit Chain for CVE-2026-57518

Versions: Pagekit CMS ≤ 1.0.18 (project archived 2023-12-01;

Pagekit CMS 1.0.18 contains a privilege escalation vulnerability in UserApiController::saveAction() that allows authenticated users holding the user: manage users permission to self-assign arbitrary custom roles. The authorization check only prevents assignment of the built-in Administrator role (hard-coded ID=3); any custom role (ID ≥ 4) — including one with elevated permissions such as system: manage packages — passes through unchecked. An attacker can exploit this to gain the system: manage packages permission, then upload and install a malicious PHP extension package containing a webshell through the admin package installer, achieving remote code execution on the server.

  • Package/component affected: pagekit/pagekitapp/system/modules/user/src/Controller/UserApiController.php (saveAction, lines 178–183)
  • Affected versions: Pagekit CMS ≤ 1.0.18 (project archived 2023-12-01; no patched release exists)
  • Risk level: High (CVSS 8.8 — CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
  • Consequences: Full server compromise. An authenticated low-privileged user with user: manage users can escalate to arbitrary code execution as the web server user (www-data).

Impact Parity

  • Disclosed/claimed maximum impact: Privilege escalation leading to remote code execution (code_execution)
  • Reproduced impact from this run: Full privilege escalation to system: manage packages, followed by upload and installation of a malicious PHP package, followed by confirmed remote code execution (uid=33(www-data))
  • Parity: full
  • Not demonstrated: N/A — the full chain from low-privilege user to arbitrary command execution was demonstrated end-to-end against the real running Pagekit service via its HTTP API.

Root Cause

The vulnerability is in UserApiController::saveAction() at app/system/modules/user/src/Controller/UserApiController.php, lines 178–183:

$key    = array_search(Role::ROLE_ADMINISTRATOR, @$data['roles'] ?: []);
$add    = false !== $key && !$user->isAdministrator();
$remove = false === $key && $user->isAdministrator();

if (($self && $remove) || !App::user()->isAdministrator() && ($remove || $add)) {
    App::abort(403, 'Cannot add/remove Admin Role.');
}

Role::ROLE_ADMINISTRATOR is a constant equal to 3 (defined in app/system/modules/user/src/Model/Role.php). The authorization check only tests whether the Administrator role (ID=3) is being added or removed. Custom roles created by an administrator (which receive IDs 4, 5, 6, …) are never subjected to any authorization check. Consequently, any user who has the user: manage users permission (required by the @Access("user: manage users") annotation on UserApiController) can call POST /api/user/{own_id} with a roles array that includes a custom role with elevated permissions — for example, system: manage packages — and the server will silently accept and persist the change.

Once the attacker holds system: manage packages (and system: access admin area), the admin package installer at POST /admin/system/package/upload and POST /admin/system/package/install becomes available. The attacker uploads a ZIP archive containing a composer.json (type pagekit-extension) and a PHP webshell (index.php). The installer extracts the package into the web-accessible packages/ directory, and the webshell is immediately reachable at /packages/pagekit/shell/index.php?cmd=<command>, executing arbitrary commands as the web server user.

Fix commit: None — the Pagekit project was archived on 2023-12-01 and no patched version has been released.

Reproduction Steps

  1. Script: bundle/repro/reproduction_steps.sh
  2. What the script does:
    • Downloads (or reuses a cached copy of) the official Pagekit 1.0.18 release ZIP (which includes all PHP dependencies in app/vendor/).
    • Builds a Docker image based on php:7.4-apache with the required PHP extensions (gd, zip, pdo_sqlite, opcache) and deploys Pagekit with Apache + mod_rewrite.
    • Starts the container and installs Pagekit via its installer API (POST /installer/install) using a SQLite database, creating an administrator account.
    • As administrator, creates two custom roles:
      • Package Manager (ID 4): system: manage packages + system: access admin area
      • User Manager (ID 5): user: manage users
    • As administrator, creates a low-privileged editor user (ID 2) with the User Manager role.
    • As editor, calls POST /api/user/2 with {"user":{"id":2,"roles":[2,4]}} — self-assigning the Package Manager role. The saveAction only blocks role ID 3 (Administrator); the custom role ID 4 passes through unchecked.
    • As the now-escalated editor, uploads a malicious extension ZIP (containing a PHP webshell) via POST /admin/system/package/upload and installs it via POST /admin/system/package/install.
    • Accesses /packages/pagekit/shell/index.php?cmd=id and verifies the output contains uid=, confirming remote code execution.
  3. Expected evidence of reproduction:
    • bundle/logs/reproduction_steps.log — full execution log
    • bundle/logs/exploit_evidence.txt — structured evidence summary
    • bundle/logs/rce_id_output.txt — output of id command via webshell (uid=33(www-data) gid=33(www-data) groups=33(www-data))
    • bundle/logs/rce_whoami_output.txt — output of whoami (www-data)
    • bundle/repro/runtime_manifest.json — runtime evidence manifest

Evidence

Key excerpts

Privilege escalation (Step 3):

Editor BEFORE escalation: {"id":2,...,"roles":[2,5],...}
Escalation response: {"message":"success","user":{"id":2,...,"roles":[2,4],...}}
PRIVILEGE ESCALATION CONFIRMED — editor now has 'system: manage packages'

RCE (Step 6):

RCE output (id): uid=33(www-data) gid=33(www-data) groups=33(www-data)
RCE output (whoami): www-data
=== RCE CONFIRMED ===
Environment details
  • OS: Ubuntu 26.04 LTS (host); Debian Bullseye (container)
  • PHP: 7.4.33 (Apache, inside Docker container)
  • Database: SQLite (pagekit.db)
  • Pagekit: 1.0.18 (official release from GitHub)
  • Web server: Apache 2.4.54 with mod_rewrite
Sandbox adaptations (non-security-relevant)
  1. Docker networking: The sandbox restricts host-to-container port forwarding, so all HTTP requests to the running Pagekit service are made via docker exec (curl inside the container). This does not alter the product's request handling — the same HTTP requests reach the same Apache
    • PHP + Pagekit stack.
  2. Session bootstrap: A PHP helper (create_session.php) creates a valid authenticated session directly in the database (session + auth tables) to bypass a PHP 7.4 / Symfony 3.0 session-storage interaction issue that prevents normal web login via curl. The auth state created is identical to a successful web login (same cookies, same database records, same CSRF token derivation).
  3. Composer marketplace repository: The package installer's Composer blueprint includes a remote composer repository pointing to https://pagekit.com. The sandbox has no outbound network, so this repository entry is removed from the blueprint, leaving only the local artifact repository. This does not change any security-relevant code path — it only avoids a network fetch for the marketplace index that is irrelevant to the exploit.

Recommendations / Next Steps

Suggested fix

The authorization check in saveAction should validate all role assignments, not just the Administrator role. A correct implementation would verify that the calling user is permitted to assign each role in the $data['roles'] array — for example, by checking that the calling user either is an administrator or holds a permission that authorizes assigning each specific role. At minimum, the check should prevent any non-administrator from assigning roles with trusted permissions (such as system: manage packages) to themselves.

Upgrade guidance

Pagekit is archived and unmaintained. Users should migrate to an actively maintained CMS. If migration is not immediately feasible, a mitigation is to never grant the user: manage users permission to non-administrator accounts, and to avoid creating custom roles with trusted permissions.

Testing recommendations
  • Add a unit test that verifies a non-administrator user with user: manage users cannot self-assign a custom role with trusted permissions.
  • Add an integration test that verifies the package installer rejects uploads from users without system: manage packages.

Additional Notes

Idempotency confirmation

The script was run twice consecutively, both times producing the same result: privilege escalation confirmed and RCE confirmed (uid=33(www-data)). Each run creates a fresh Docker container with a clean Pagekit installation, ensuring no state carries over between runs.

Limitations
  • The project is archived; no fixed version exists for a negative control.
  • The webshell executes as www-data (the Apache user), not as root. Full root compromise would require a separate local privilege escalation, which is out of scope for this CVE.
  • The user: manage users precondition is realistic: Pagekit supports delegating user management to non-owner accounts (e.g., a "User Manager" or "Editor" role), which is the exact scenario this vulnerability targets.

CVE-2026-57518 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:41
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-57518 · REPRO-20
0:01
0:03
web search
0:05
web search
0:08
0:09
0:11
web search
0:14
0:16
0:18
0:19
web search
0:27
0:27
extract_facts
no facts extracted
0:28
0:28
0:28
supportrepro
0:30
0:30
0:30
0:31
0:31
0:32
0:32
0:33
0:35
0:37
web search
0:38
web search
0:41
08 · How to Fix

How to Fix CVE-2026-57518

Upgrade pagekit/pagekit · github to None available; project archived or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-57518 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-57518

How does the CVE-2026-57518 escalation-to-RCE chain work?

A user holding user: manage users self-assigns a custom role (ID >= 4) that carries system: manage packages, then uses the resulting admin package-installer functionality to upload and install a malicious PHP extension package containing a web shell, achieving remote code execution as the web server user.

Which Pagekit versions are affected by CVE-2026-57518, and where is it fixed?

Pagekit CMS <= 1.0.18 is affected. The project is archived (as of 2023-12-01) and no patched release is available.

How severe is CVE-2026-57518?

High severity, CVSS 3.1 8.8, reflecting full server compromise achievable from an authenticated low-privileged account.

How can I reproduce CVE-2026-57518?

Download the verified script and run it in an isolated environment against Pagekit 1.0.18; it creates a low-privileged user with user: manage users, self-assigns a custom role granting system: manage packages, then uploads a malicious PHP package via the admin installer to confirm code execution as www-data.
11 · References

References for CVE-2026-57518

Authoritative sources for CVE-2026-57518 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.