| Package Name | Ecosystem | Vulnerable Versions | First Patched Version |
|---|---|---|---|
| pretix | pip | >= 2025.10.0, < 2025.10.1 | 2025.10.1 |
| pretix | pip | >= 2025.9.0, < 2025.9.3 | 2025.9.3 |
| pretix | pip | < 2025.8.3 | 2025.8.3 |
The vulnerability, identified as CVE-2025-14881, is a Broken Access Control issue in pretix. Multiple endpoints allowed unauthorized access to files stored as CachedFile objects. The root cause was that these endpoints retrieved files using their unique identifiers (UUIDs or primary keys) without properly verifying that the user making the request was the one who originally created or was granted access to the file.
The patch addresses this by introducing a session-binding mechanism. When a CachedFile is created, it is now explicitly bound to the user's current session (or API token) by storing a derived session key in the CachedFile.session_key field. The new allowed_for_session method was added to the CachedFile model to centralize the authorization logic.
My analysis of the commit 4b5651862c57c6e384822d1d23292342126c479a reveals several functions where this check was missing and subsequently added. These functions are the direct points of vulnerability:
ExportersViewSet.download: This API endpoint for downloading exported files fetched the file by ID without checking ownership.DownloadView.object: A generic view for downloading files, it had a weak session check that was replaced with the new, more secure method.ImportView.file: This property, used in a data import view, fetched an uploaded file without verifying the user's session.ShredderStart.get_context_data: This view, used for data shredding, accessed file metadata without proper authorization.BaseEditor.post: This view allowed fetching a file via a POST request parameter without sufficient checks.During an exploit, a profiler would show one of these function names in the stack trace when an attacker makes a request with a known file ID that does not belong to them. The functions identified are the exact locations where the insufficient authorization occurred.
ExportersViewSet.downloadsrc/pretix/api/views/exporters.py
DownloadView.objectsrc/pretix/base/views/cachedfiles.py
ImportView.filesrc/pretix/control/views/modelimport.py
ShredderStart.get_context_datasrc/pretix/control/views/shredder.py
BaseEditor.postsrc/pretix/control/views/pdf.py
A Semantic Attack on Google Gemini - Read the Latest Research