{"schema":"threatline.record/2","record":{"id":"GHSA-2pvc-r9gj-mcpf","aliases":["GHSA-2pvc-r9gj-mcpf"],"summary":"Flex Objects API serves pages without the Pages API permission checks","details":"## Summary\n\nThe Flex Objects plugin provides generic API routes for every enabled Flex directory, including the built-in `pages` directory (`/api/v1/flex-objects/pages/...`). Those routes checked only the directory-level `admin.pages.*` permission. They did not apply what the Pages API (`/api/v1/pages/...`) applies to the same content: the `api.pages.read` and `api.pages.write` permissions and the page's own `permissions` rules. A signed-in, non-super account with API access could read, change or delete pages that the Pages API refuses it.\n\n## Affected versions\n\nFlex Objects 1.4.0 through 1.4.16, on Grav 2.x with the API plugin enabled. The `pages` Flex directory is enabled by default. Sites that rely on page-level `permissions` rules are affected when running API plugin 1.0.16 or later, the first version where the Pages API enforces those rules.\n\n## Details\n\n`FlexApiController` authorizes list, read, create, update, delete and media requests against the permission prefixes declared in the directory blueprint. For pages those are `admin.pages` and `admin.configuration.pages`. Once that check passed, the requested page was returned, saved or deleted with no further check.\n\nThe Pages API authorizes each request per page: a rule in the page's `permissions` frontmatter (or an inherited one) that denies the action is final, and otherwise the account needs `api.pages.read` or `api.pages.write`. None of this ran on the generic route, so:\n\n- an account denied by a page's own rules could still read the page's Markdown and frontmatter, overwrite its content, and delete it;\n- an account holding `admin.pages.*` but no `api.pages.*` permission could do the same to any page;\n- because permissions resolve through parent keys, an account holding only the pages configuration permission (`admin.configuration.pages`) was treated as holding page read, update and delete.\n\nThe original report covers the first case. The other two were found while confirming it. The account needs `api.access` and one of the permissions above. Super users already hold these capabilities.\n\n## Impact\n\nA non-super account can read page source and frontmatter that is never rendered, change what a page publishes, and delete pages, in each case for pages it was explicitly denied or was never granted. The impact is limited to page content. It does not give access to accounts or configuration, and it does not let the account turn on Twig processing for a page.\n\n## Patches\n\nFixed in Flex Objects 1.4.17. Pages are no longer served by the generic Flex Objects API routes. Requests to `/api/v1/flex-objects/pages` and below return 403, and pages are read and written only through the Pages API. API clients that used the generic route for pages need to switch to `/api/v1/pages`.\n\nIf you cannot update right away, remove `admin.pages` and `admin.configuration.pages` from non-super accounts and groups, or remove `api.access` from accounts that do not need the API.\n\n## Credits\n\nReported by @ffasterss and @shirabe0x05 of Omoikane Labs.\n","categories":["Unclassified"],"product":"getgrav/grav-plugin-flex-objects","vendor":"","ecosystem":null,"affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/getgrav/grav/security/advisories/GHSA-2pvc-r9gj-mcpf","source_modified_at":"2026-10-07T03:04:20Z","fetched_at":"2026-10-25T18:55:31.805249Z","package":{"ecosystem":"composer","name":"getgrav/grav-plugin-flex-objects"},"range":">= 1.4.0, < 1.4.17"}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/getgrav/grav/security/advisories/GHSA-2pvc-r9gj-mcpf","source_modified_at":"2026-10-07T03:04:20Z","fetched_at":"2026-10-25T18:55:31.805249Z","package":{"ecosystem":"composer","name":"getgrav/grav-plugin-flex-objects"},"version":"1.4.17"}],"cvss":null,"severity":"Medium","kev":{"listed":false},"epss":{"probability":null,"percentile":null,"score_date":null},"published_at":"2026-10-07T03:04:20Z","modified_at":"2026-10-07T03:04:20Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/getgrav/grav/security/advisories/GHSA-2pvc-r9gj-mcpf","fetched_at":"2026-10-25T18:55:31.805249Z","source_modified_at":"2026-10-07T03:04:20Z"}],"sources":["GitHub Advisory Database"],"references":[],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":null,"confidence":"unknown","reviewed":false},"change_timestamp":"2026-10-07T03:04:20Z","content_hash":"2a58e36ba85b68c33cdae8b478cea13d8e993d33dd001b4293c9ebc07c6f702c"}}
