CVE-2026-107850 Overview
CVE-2026-107850 is a broken access control vulnerability [CWE-639] in Contao, an open source content management system. The flaw affects versions 5.7.1 through 5.7.11 and resides in the core-bundle/config/services.yaml configuration. A service misregistration causes the PreviewVoter ownership check to never execute, allowing non-admin backend users with the preview_link module to enumerate preview links created by other users. Attackers can then use the signed share URLs to view unpublished pages via showUnpublished without holding page permissions.
Critical Impact
Authenticated backend users can list every tl_preview_link record and reuse other users' signed URLs to access unpublished content they otherwise cannot view.
Affected Products
- Contao CMS 5.7.1 through 5.7.11
- Contao core-bundle preview link module
- Contao installations exposing the preview_link module to non-admin backend users
Discovery Timeline
- 2026-10-09 - CVE-2026-107850 published to NVD
- 2026-10-16 - Last updated in NVD database
Technical Details for CVE-2026-107850
Vulnerability Analysis
The vulnerability stems from a class name mismatch in Symfony service configuration. The file core-bundle/config/services.yaml registers the preview access voter under the class Contao\CoreBundle\Security\Voter\DataContainer\PreviewAccessVoter, but the shipped class is actually PreviewVoter. Symfony cannot resolve the declared class, so it omits voter autoconfiguration and removes the private service from the container.
The practical result is that PreviewVoter::hasAccess() never executes against listing or record access requests. The data container for tl_preview_link therefore returns every record regardless of the createdBy ownership field. A backend user with permission to use the preview_link module gains visibility into links created by other users, including the signed share tokens embedded in those URLs.
The advisory confirms that this flaw only exposes read access to preview link records and the generated share URLs. It does not establish the ability to edit or delete links owned by other users.
Root Cause
The root cause is a service definition referencing a non-existent class name. Symfony's dependency injection container silently drops the service when autoconfiguration cannot bind the voter interface, bypassing the intended access control layer entirely.
Attack Vector
A non-admin backend user authenticated to the Contao backend navigates to the preview link module. The listing view returns all tl_preview_link rows across all users rather than only those where createdBy matches the current user. The attacker copies the signed share URL from any listed record and loads it in a browser. The share URL activates showUnpublished, rendering pages that are not yet published to anonymous visitors.
#[AsCallback(table: 'tl_preview_link', target: 'config.onload')]
public function createFromUrl(DataContainer $dc): void
{
+ $user = $this->security->getUser();
+
+ if (!$this->security->isGranted('ROLE_ADMIN')) {
+ $GLOBALS['TL_DCA']['tl_preview_link']['list']['sorting']['filter'][] = ['createdBy = ?', $user instanceof BackendUser ? (int) $user->id : 0];
+ }
+
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return;
}
- $user = $this->security->getUser();
$act = $request->query->get('act');
$url = $request->query->getString('url');
$now = $this->clock->now();
Source: GitHub Commit 6b483d3. The patch enforces a createdBy filter in PreviewLinkListener::createFromUrl() so non-admin users only see their own records.
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-107850
Indicators of Compromise
- Backend audit log entries showing non-admin users accessing the tl_preview_link listing with result counts exceeding their own owned records.
- Access log requests to preview share URLs where the requesting session's user ID differs from the createdBy value on the referenced link.
- Rendering of unpublished pages via query parameters that include showUnpublished originating from signed URLs not issued to the viewing user.
Detection Strategies
- Compare tl_preview_link.createdBy against the authenticated session identifier on every backend list request and alert when results include foreign records.
- Review HTTP access logs for the preview share endpoint and correlate signed URL token usage against the issuing user's active sessions.
- Query database audit tables for SELECT statements against tl_preview_link originating from accounts without ROLE_ADMIN.
Monitoring Recommendations
- Enable Contao backend action logging and forward records to a centralized log platform for retention and analytics.
- Track the Symfony service container at deployment time to flag voters that fail to register under the security.voter tag.
- Alert on any growth in distinct preview link accesses per non-admin user that exceeds historical baselines.
How to Mitigate CVE-2026-107850
Immediate Actions Required
- Upgrade Contao to version 5.7.12 or later to restore the ownership check on preview link listings.
- Audit tl_preview_link records and revoke or regenerate signed share URLs created during the vulnerable window.
- Review backend user permissions and remove the preview_link module from accounts that do not require it.
Patch Information
The fix is released in Contao 5.7.12. The corrective change in PreviewLinkListener::createFromUrl() applies a DCA filter restricting the listing to records where createdBy matches the current BackendUser identifier when the user does not hold ROLE_ADMIN. See the GitHub Security Advisory GHSA-q6wp-fr43-gm9v and the GitHub Release 5.7.12 for release notes.
Workarounds
- Restrict the preview_link backend module to administrators until the upgrade is applied.
- Expire or delete existing preview links so previously leaked signed URLs no longer resolve.
- Disable showUnpublished rendering at the reverse proxy for requests that do not originate from administrator sessions.
# Upgrade Contao core-bundle via Composer
composer require contao/core-bundle:^5.7.12 --update-with-all-dependencies
composer update contao/core-bundle
vendor/bin/contao-console cache:clear --env=prod
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

