Area: mobieusKnow (audit p6) · Surface: POST /api/v1/know/revisions/{id}/approve|reject, /api/v1/know/pages/{slug}, /pages/{slug}/delete, /pages (KnowledgeApiController) · Dimension: security · Severity: major
OWASP A01:2021 Broken Access Control. The API surface collapses the entire web-side trust/moderation model into a single coarse scope. Any key holder with know:write — not necessarily a moderator — can approve or reject arbitrary revisions, hard-bypass the review queue by publishing approved revisions directly, edit or delete any page, with no ownership or moderator gate. The web path forbids exactly these actions for non-moderators.
Evidence
Every write method gates ONLY on the know:write scope and performs no role/moderator/ownership check. KnowledgeApiController.php:196-210 revisionsApprove(): `$this->requireScope(ApiKey::SCOPE_KNOW_WRITE);` then directly `UPDATE knowledge_revisions SET status="approved"...` and points the page at it. revisionsReject (213-230), pagesDelete (159-166), pagesUpdate (123-156), pagesCreate (87-120) are identical. requireScope (V1Controller.php:31-41) only checks `in_array($scope, $key['scopes'])` — no user role lookup. By contrast the web equivalents require a moderator: KnowledgeController::approveRevision (381-406) and deletePage (538-555) enforce `if (!KnowledgeTrust::isModerator(...) && (int)$user['role'] < 4)`, and pagesCreate/pagesUpdate via the API hardcode `status => 'approved'` (lines 113, 144) skipping the pending queue that KnowledgeController::store applies to untrusted users (KnowledgeController.php:165 `$canPublish ? 'approved' : 'pending'`).
Suggested fix. Add a moderator-only check for approve/reject/delete on the API (e.g. resolve the key creator's role / a know:moderate scope) and make pagesCreate/pagesUpdate respect the same trust rule the web path uses (KnowledgeTrust::canPublishDirectly) so non-trusted authors land in 'pending', not 'approved'.
Filed by the automated tenant-app audit and adversarially evidence-verified. Status: verified. Open — not yet actioned.
Patrick Bass
@mobieus