CVE-2026-62670 Overview
CVE-2026-62670 is a missing authorization vulnerability [CWE-862] in the Grav Flex Objects Plugin affecting versions prior to 1.4.3. The requireFlexPermission() method in classes/Api/FlexApiController.php returns without denying access when a directory blueprint omits config.admin.permissions. Authenticated accounts holding only api.access can invoke the index, show, create, update, delete, export, and media handlers against permission-less directories. The core admin.flex-object.* authorization fallback would normally deny these actions. The maintainers fixed the flaw in version 1.4.3.
Critical Impact
Low-privileged authenticated users can read, modify, and delete Flex Objects data through the admin-next API, bypassing the intended core authorization gate.
Affected Products
- Grav Flex Objects Plugin versions prior to 1.4.3
- Grav CMS installations exposing the Flex Objects Admin Next API
- Directory blueprints that omit config.admin.permissions
Discovery Timeline
- 2026-08-19 - CVE-2026-62670 published to NVD
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-62670
Vulnerability Analysis
The Flex Objects plugin exposes an admin-next REST API for managing custom object collections. Access control runs through FlexApiController::requireFlexPermission(), which reads admin.permissions from the directory blueprint. When the blueprint defines permissions, the method iterates each prefix and grants access if the user holds any matching capability. When the blueprint omits admin.permissions, the vulnerable code path exits without evaluating any fallback authorization. An authenticated user needs only the api.access capability to reach the controller. From there, the index, show, create, update, delete, export, and media handlers execute against the target directory. The listing endpoint (directories()) applies the core admin.flex-object.<action> gate, so the API surface behaves inconsistently with the rest of the admin UI.
Root Cause
The root cause is a missing default-deny branch. The pre-patch logic treats an absent permissions array as implicit approval rather than falling back to Directory::isAuthorized($action, 'admin', $user). This diverges from the authorization model used elsewhere in Grav admin.
Attack Vector
An attacker authenticates to the Grav instance with an account that has only the api.access right. The attacker enumerates Flex directories and issues requests against any directory whose blueprint omits admin.permissions. Each handler executes as if the user were authorized, allowing data disclosure, mutation, or deletion.
// Source: https://github.com/trilbymedia/grav-plugin-flex-objects/commit/198d1a0eb7b94777a026ed0001d9a369d94c3002
// Patch in classes/Api/FlexApiController.php - deny permission-less flex directories
// Blueprints may define both admin.* and api.* permissions — check all
// registered prefixes (OR: any matching permission grants access).
$permissions = $directory->getConfig('admin.permissions');
- if ($permissions) {
- foreach ($permissions as $prefix => $config) {
- $permission = $prefix . '.' . $action;
- if ($this->hasPermission($user, $permission)) {
- return;
- }
+ if (!$permissions) {
+ // No blueprint-defined permissions: defer to core's authorization
+ // rules (admin.flex-object.<action>) rather than allowing access.
+ // Mirrors the gate used by directories() when listing directories.
+ if (!$directory->isAuthorized($action, 'admin', $user)) {
+ throw new \Grav\Plugin\Api\Exceptions\ForbiddenException(
+ "Missing required permission for '{$directory->getFlexType()}'.",
+ );
+ }
+ return;
+ }
+
+ foreach ($permissions as $prefix => $config) {
+ $permission = $prefix . '.' . $action;
+ if ($this->hasPermission($user, $permission)) {
+ return;
}
- // None matched — report the first prefix for a clear error
- $prefix = array_key_first($permissions);
- throw new \Grav\Plugin\Api\Exceptions\ForbiddenException("Missing required permission: {$prefix}.{$action}");
}
The patch adds an explicit default-deny branch. When admin.permissions is missing, control now defers to $directory->isAuthorized($action, 'admin', $user) and throws ForbiddenException when that check fails.
Detection Methods for CVE-2026-62670
Indicators of Compromise
- Requests to /api/* admin-next endpoints from accounts holding only the api.access capability.
- Successful index, show, create, update, delete, export, or media handler invocations against Flex directories whose blueprints lack admin.permissions.
- Unexpected modifications or deletions of Flex Objects records outside of admin UI sessions.
Detection Strategies
- Audit Flex directory blueprints and flag any that omit config.admin.permissions.
- Correlate web-server access logs with user role assignments to identify low-privilege accounts hitting Flex API routes.
- Compare pre- and post-request Flex data snapshots to detect unauthorized mutations.
Monitoring Recommendations
- Log all authenticated requests to Flex admin-next API endpoints along with the acting user identity.
- Alert on any non-administrator account exercising create, update, delete, or export handlers.
- Track version strings of the grav-plugin-flex-objects package across environments to confirm patched builds are deployed.
How to Mitigate CVE-2026-62670
Immediate Actions Required
- Upgrade the Grav Flex Objects Plugin to version 1.4.3 or later.
- Review all Flex directory blueprints and add explicit admin.permissions entries where missing.
- Restrict issuance of the api.access capability to trusted service accounts only.
Patch Information
The fix is available in Grav Flex Objects Plugin 1.4.3. Details are published in the GitHub Security Advisory GHSA-23vq-365v-qcmh, the remediation commit 198d1a0, and the 1.4.3 release notes.
Workarounds
- Disable the Flex Objects admin-next API on internet-facing instances until the patch is applied.
- Revoke api.access from any account that does not require programmatic Flex management.
- Add config.admin.permissions blocks to every Flex directory blueprint so authorization checks resolve through the defined prefixes.
# Upgrade via Grav CLI
bin/gpm update flex-objects
# Verify installed version is 1.4.3 or later
bin/gpm info flex-objects | grep -i version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

