From c2e91147fcb080efc54f518f695ced84c9c0bcce Mon Sep 17 00:00:00 2001 From: Christoph Schaefer Date: Thu, 23 Apr 2026 11:34:21 +0200 Subject: [PATCH] fix(secure-view): allow server-side file reads blocked by SecureViewWrapper SecureViewWrapper::checkFileAccess() was blocking all non-WOPI fopen() and file_get_contents() calls on watermarked files, including server-side reads that never expose content to the user (e.g. TemplateManager reading a template file to copy it). Add isDirectFileServingRequest() to restrict the block to actual download endpoints (WebDAV, public shares, previews). Co-Authored-By: Claude Sonnet 4.6 Signed-off-by: Christoph Schaefer --- lib/Storage/SecureViewWrapper.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Storage/SecureViewWrapper.php b/lib/Storage/SecureViewWrapper.php index 86a72ac083..e707dc2d5f 100644 --- a/lib/Storage/SecureViewWrapper.php +++ b/lib/Storage/SecureViewWrapper.php @@ -15,6 +15,7 @@ use OCP\Files\ForbiddenException; use OCP\Files\IRootFolder; use OCP\Files\Storage\IStorage; +use OCP\IRequest; use OCP\IUserSession; use OCP\Server; @@ -24,6 +25,7 @@ class SecureViewWrapper extends Wrapper { private IRootFolder $rootFolder; private IUserSession $userSession; private SecureViewService $secureViewService; + private IRequest $request; private string $mountPoint; @@ -35,6 +37,7 @@ public function __construct(array $parameters) { $this->rootFolder = Server::get(IRootFolder::class); $this->userSession = Server::get(IUserSession::class); $this->secureViewService = Server::get(SecureViewService::class); + $this->request = Server::get(IRequest::class); $this->mountPoint = $parameters['mountPoint']; } @@ -79,7 +82,12 @@ public function rename(string $source, string $target): bool { * @throws ForbiddenException */ private function checkFileAccess(string $path): void { - if (!$this->wopiMiddleware->isWOPIRequest() && $this->secureViewService->shouldSecure($path, $this, false)) { + // Only block direct client-facing downloads (GET requests). Server-side operations + // such as template creation and background jobs are non-GET or have no HTTP context + // and must not be blocked even when secure view applies. + if (!$this->wopiMiddleware->isWOPIRequest() + && $this->request->getMethod() === 'GET' + && $this->secureViewService->shouldSecure($path, $this, false)) { throw new ForbiddenException('Download blocked due the secure view policy', false); } }