tine: The File Preview Shows HTML Files in a Same-Origin Frame
QuickLook embeds a stored HTML file without sandbox, and the serving path sends neither nosniff nor a CSP.
Advisory ID: TP-2026-099
Product: tine (groupware and CRM, PHP)
Vulnerability type: Stored cross-site scripting (CWE-79)
CVE: requested (GitHub CNA), assignment pending
CVSS 3.1: 8.0 (High) · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H
Affected versions: <= 2025.11.12
Vendor advisory: GHSA-f2cp-xjc8-5frq
Fixed in: 2024.11.23, 2025.11.13 and weekly-2026.35.1
Reported: 21 August 2026
Summary
tine's Filemanager offers a quick preview for stored files, and for the type text/html it builds an embedded frame with no sandbox attribute. The serving path returns the file with its stored type and for immediate display, requires only a read right for that, and sends neither X-Content-Type-Options nor a Content-Security-Policy nor X-Frame-Options. A low-privilege user therefore uploads an HTML file and shares it into a folder the victim may read. When the victim opens the preview, the stored script runs in tine's origin. From there it reads the anti-CSRF key out of the registry data and calls privileged methods in the victim's name.
Root cause
QuickLookHTMLPanel registers text/html for preview and renders the file in a same-origin frame with no sandbox attribute, appending disposition=inline to the download URL (tine20/Filemanager/js/QuickLookHTMLPanel.js:20,29). The downloadFile method takes disposition as a client parameter (tine20/Filemanager/Frontend/Http.php:30), and for inline display the serving path _downloadFileNode requires only GRANT_READ (tine20/Tinebase/Frontend/Http/Abstract.php:351). The file is served with its stored content type, which the server derives from the content on upload, and without X-Content-Type-Options: nosniff. The application also sets neither a Content-Security-Policy nor X-Frame-Options, so nothing separates the uploaded file from tine's origin.
Proof of Concept
# 1. as a low-privilege user, upload a file with the content:
<script>
const d = Tinebase.getAllRegistryData();
fetch('/index.php?method=Tinebase.getAllRegistryData&jsonKey=' + d.jsonKey);
</script>
# 2. share the file into a folder the victim may read,
# for instance through a personal-folder share or a team folder.
# 3. the victim opens the QuickLook preview in the Filemanager
# -> the frame loads the file as text/html with no sandbox,
# and the script runs in tine's origin.
The jsonKey it reads is the only protection against cross-site requests, so the script then makes arbitrary JSON-RPC calls in the victim's name.
Impact
- Takeover of any account whose holder opens the shared file in the preview, up to and including an administrator.
- Disclosure of the anti-CSRF key and with it authenticated calls in the victim's name.
- Access to all data the victim may see, that is mail, address book, calendar and files.
- Reachable in a stock install, since the shipped Users group carries the Filemanager.
References
Is Something Like This in Your Software?
Our team found this vulnerability in the course of its work. Have your applications tested by the same specialists, with a penetration test from turingpoint.
