CVE-2026-104189 in 3Dviewer Nextcloud
Summary
by MITRE • 10/27/2026
The 3D Viewer for Nextcloud is a comprehensive 3D model viewer application for Nextcloud that supports multiple 3D file formats. In versions 1.7.9 through 3.3.1, the app's public file endpoint performed no share authorization. Anyone who knows a share token could read the shared file's contents even when the link share was protected by a password. `PublicFileController` extended `OCP\AppFramework\Controller` and marked its routes `#[PublicPage]`. Nextcloud only enforces share passwords through `PublicShareMiddleware`, which returns early for any controller that is not an `OCP\AppFramework\PublicShareController` instance — so no password, expiry, or share-type check ran for these routes. `ShareFileService::loadLinkShare()` compounded this by treating any token that `getShareByToken()` matched as authorised. A share token is the part of the URL that people paste into chats, emails, and tickets. Password protection exists precisely for the case where holding the token should not by itself grant access, and that guarantee did not hold. Requests to `GET /ocs/v2.php/apps/threedviewer/public/file/{token}/{fileId}` returned `200` with the full file body for password-protected shares, with no password and no session. Nextcloud's own share page correctly redirected such requests to the password prompt. Scope is limited to files in the formats this app handles (STL, GLB/glTF, OBJ, STEP, IFC, and the other supported 3D types). Non-3D files in the same share are unaffected. Expired shares returned `500` rather than leaking contents. This issue is fixed in 3.3.2. `PublicFileController` now extends `PublicShareController` and implements `isValidToken()`, `isPasswordProtected()`, and `getPasswordHash()`, delegating password and token validation to the framework and gaining brute-force throttling. `ShareFileService::findValidLinkShare()` additionally rejects share types other than link and email, rejects expired shares, and treats a `ShareNotFound` from the share manager as "no share" instead of letting it surface as a 500. As a workaround, disable the 3D Viewer app (`occ app:disable threedviewer`), or avoid relying on passwords to protect link shares that contain 3D model files, until you can upgrade.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/27/2026
The vulnerability identified in versions 1.7.9 through 3.3.1 of the 3D Viewer for Nextcloud represents a critical authentication bypass within the application's public file sharing mechanism. The core technical flaw stems from an incorrect inheritance hierarchy and missing authorization checks in the `PublicFileController` class. Specifically, this controller extended `OCP\AppFramework\Controller` rather than `OCP\AppFramework\PublicShareController`. In the Nextcloud framework architecture, security middleware such as `PublicShareMiddleware`, which is responsible for enforcing share passwords, expiration dates, and share type validations, only executes its logic if the target controller instance is an instance of `PublicShareController`. Because the 3D Viewer's public endpoint did not meet this criteria, the middleware returned early without performing any security checks. Consequently, requests to the public file endpoint were processed by a route marked with `[PublicPage]` but devoid of the necessary password verification logic, allowing anyone possessing the share token to access the underlying data regardless of whether the link was protected by a password.
This flaw effectively nullifies the primary purpose of password-protected shares, which is to ensure that possession of the URL or share token alone does not grant unauthorized access. An attacker who obtains a valid share token through phishing, social engineering, or accidental exposure can directly request the file via `GET /ocs/v2.php/apps/threedviewer/public/file/{token}/{fileId}` and receive an HTTP 200 response containing the full binary content of the 3D model. This behavior contrasts sharply with Nextcloud's standard share page implementation, which correctly intercepts such requests and redirects them to a password prompt when protection is enabled. The vulnerability also highlights a secondary issue within `ShareFileService::loadLinkShare()`, where any token matched by `getShareByToken()` was treated as authorized without further validation of the share state or expiration status. While expired shares incorrectly returned an HTTP 500 error rather than leaking data, this indicates poor error handling and potential information leakage through stack traces if not properly configured to suppress such details in production environments.
From a risk perspective, this vulnerability allows for unauthorized disclosure of sensitive intellectual property contained within 3D model files, including formats like STL, GLB/glTF, OBJ, STEP, and IFC. The impact is strictly limited to these specific file types handled by the application; non-3D files shared via the same link remain protected by standard Nextcloud mechanisms because they are served through different controllers that correctly inherit from `PublicShareController`. This distinction underscores the importance of verifying security implementations across all endpoints within an application, as inconsistent handling can create isolated but critical weaknesses. The vulnerability aligns with CWE-287 (Improper Authentication) and CWE-306 (Missing Authentication for Critical Function), reflecting a failure to enforce authentication controls on sensitive resources. In terms of the MITRE ATT&CK framework, this behavior facilitates unauthorized data access by bypassing established security boundaries, potentially enabling adversaries to exfiltrate proprietary design files or other confidential information shared via Nextcloud links.
The issue was resolved in version 3.3.2 through a comprehensive refactoring of the public file handling logic. The `PublicFileController` was updated to extend `PublicShareController`, thereby ensuring that it is subject to the framework's standard security middleware and brute-force throttling mechanisms. Additionally, the controller now implements specific methods such as `isValidToken()`, `isPasswordProtected()`, and `getPasswordHash()` to explicitly delegate password validation to the core system rather than relying on implicit behavior. The underlying service layer was also hardened; `ShareFileService::findValidLinkShare()` now strictly rejects share types other than link and email, validates expiration status to prevent access to expired shares, and properly handles `ShareNotFound` exceptions by treating them as unauthorized access attempts rather than returning generic server errors. To mitigate the risk in unpatched environments, administrators are advised to disable the 3D Viewer application using the command `occ app:disable threedviewer`. Alternatively, organizations should avoid relying on password protection for link shares containing sensitive 3D model files until an upgrade to version 3.3.2 or later can be performed.