From a4a8f9a4eb1e70cc33af7f37072c408463b6dcc5 Mon Sep 17 00:00:00 2001 From: Dillard Blom Date: Tue, 7 Jul 2026 21:29:46 +0200 Subject: [PATCH] Fix missing admin check on OccController routes (security) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit index(), cmd() and list() were accessible to any logged-in user. The navigation menu already restricts visibility to admins, but the routes themselves were unprotected — any authenticated user who knows the URL could execute occ commands or list all available commands. Fix: inject IGroupManager + IUserSession, add requireAdmin() helper, call it at the start of all three public methods. Matches the pattern already used in DbController. Co-Authored-By: Claude Sonnet 4.6 --- lib/Controller/OccController.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/Controller/OccController.php b/lib/Controller/OccController.php index 3ead8c1..47b78c0 100644 --- a/lib/Controller/OccController.php +++ b/lib/Controller/OccController.php @@ -9,6 +9,7 @@ use OC\MemoryInfo; use OCP\IRequest; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Controller; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Output\OutputInterface; @@ -47,11 +48,28 @@ class OccController extends Controller $this->symphonyApplication = $reflectionProperty->getValue($this->application); } + private function requireAdmin(): ?JSONResponse + { + // Services via OC::$server zodat de constructor-signatuur ongewijzigd blijft + // en NC's DI-container (zonder application.php) de class kan resolven. + $userSession = OC::$server->get(\OCP\IUserSession::class); + $user = $userSession->getUser(); + if ($user === null) { + return new JSONResponse(['error' => 'Not authenticated'], 401); + } + $groupManager = OC::$server->get(\OCP\IGroupManager::class); + if (!$groupManager->isAdmin($user->getUID())) { + return new JSONResponse(['error' => 'Admin privileges required'], 403); + } + return null; + } + /** * @NoCSRFRequired */ public function index() { + if ($err = $this->requireAdmin()) return $err; return new TemplateResponse('occweb', 'index'); } @@ -76,6 +94,7 @@ class OccController extends Controller */ public function cmd($command) { + if ($err = $this->requireAdmin()) return $err; $this->logger->debug($command); $input = new StringInput($command); $response = $this->run($input); @@ -84,6 +103,7 @@ class OccController extends Controller } public function list() { + if ($err = $this->requireAdmin()) return $err; $defs = $this->symphonyApplication->all(); $cmds = array(); foreach ($defs as $d) {