CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-C2XX-CJMH-9Q8F

GHSA-C2XX-CJMH-9Q8F: Information Disclosure via Inherited Collection View Restriction Bypass in Wagtail API v2

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 21, 2026·6 min read·19 visits

Executive Summary (TL;DR)

Unauthenticated users can exploit Wagtail's API V2 to enumerate and leak metadata of protected images and documents by leveraging a logical flaw where descendant collections fail to inherit parent access restrictions during API queries.

An improper access control vulnerability in Wagtail's Documents and Images API V2 allows unauthenticated remote attackers to retrieve metadata (including titles and filenames) of files residing inside descendant collections of private parent collections, bypassing inherited view restrictions.

Vulnerability Overview

Wagtail CMS contains a security vulnerability in its media management architecture that exposes sensitive metadata to unauthorized clients. The platform permits administrators to structure media assets hierarchically through a collections subsystem built on Django models. This layout enforces organizational isolation and access control boundaries. The system exposes these assets via public endpoints in the Wagtail Documents and Images API V2.\n\nUnder default configurations, endpoints designed to output public media do not validate ancestral tree structures when assessing view restrictions. While parent collections can be explicitly restricted to authenticated groups or specific passwords, child collections fail to inherit these boundaries when evaluated by the API. This vulnerability is classified as an improper access control issue under CWE-200, CWE-284, and CWE-276.\n\nThis systemic failure allows unauthenticated remote attackers to query the API and list administrative properties of assets inside protected hierarchies. The exposed data includes document names, asset titles, and download path strings. Although the actual file binary access might require separate authentication, leaking asset directories weakens the organizational security posture.

Root Cause Analysis

The root cause of this vulnerability lies in the logical implementation of the collection query filters within Wagtail's API viewsets. Wagtail structures collections hierarchically using the django-treebeard library, which implements a materialized path tree pattern. To implement security boundaries, Wagtail stores restriction parameters in the CollectionViewRestriction model, specifying which collection nodes require authentication.\n\nWhen a client sends a request to the Documents or Images API, the backend filters the target queryset to present only public entities. The vulnerable query filtered collections using a direct relational check, specifically searching for collections that had no direct view restriction entry (restrictions__isnull=True). This direct query ignores the tree taxonomy, meaning it checks only for a direct database relation on that specific node.\n\nBecause nested descendant collections do not typically contain direct duplicate CollectionViewRestriction records, they evaluated to True for the restrictions__isnull lookup. This execution bypasses the expected recursive inheritance logic of the tree. Consequently, the API treats descendant collections as fully public, allowing administrative filenames and metadata to be leaked to external API consumers.

Code Analysis

The vulnerable code path utilized an overly simplistic approach to identify public files. It filtered media based on whether their direct collections lacked explicit restrictions. The code failed to traverse the ancestor path chain to check if a parent collection was marked restricted.\n\nTo resolve this, the patch introduces recursive tree-path checking. By querying the CollectionViewRestriction model, Wagtail retrieves the paths of all directly restricted collections. It then constructs a Django query that excludes any collection whose tree path starts with any of those restricted paths. Because django-treebeard uses materialized path strings, checking if a path starts with a parent's path matches the parent and all nested descendants.\n\npython\n# Patched implementation in Wagtail collections query framework\nfrom django.db import models\nfrom wagtail.models import CollectionViewRestriction, Collection\n\ndef public(self):\n # Extract paths of collections with active restrictions\n restricted_paths = CollectionViewRestriction.objects.values_list(\n 'collection__path', flat=True\n )\n \n if not restricted_paths:\n return self\n \n # Dynamically build Q object to match restricted paths and descendants\n query = models.Q()\n for path in restricted_paths:\n # Using tree path starts-with pattern to isolate the tree branch\n query |= models.Q(path__startswith=path)\n \n # Exclude all matched paths from the public collection queryset\n return self.exclude(query)\n\n\nmermaid\ngraph LR\n Parent["Restricted Parent Collection\nPath: '00010001'"] --> Child["Nested Child Collection\nPath: '000100010002'"]\n Child --> File["Confidential Document"]\n API["API V2 Query"] -.->|Bypasses restriction| Child\n style API stroke:#f66,stroke-width:2px\n\n\nWe assess this patch as highly robust and complete. Utilizing the tree's materialized path properties guarantees that no depth of nesting can bypass the constraint. This mechanism relies on Django's low-level database query compiler, which prevents logical race conditions and ensures that the restriction filter is executed directly at the database level before serialization.

Exploitation and Payload Analysis

Exploitation of this vulnerability requires no prior authentication and minimal network complexity. The attacker only needs network access to the public API endpoints. This setup is common in headless Wagtail architectures where the frontend queries the Wagtail backend via API calls.\n\nTo execute the attack, an unauthorized agent sends an HTTP GET request to the target API endpoints. The default routes are /api/v2/images/ or /api/v2/documents/. Under a vulnerable installation, the server returns a complete list of documents or images that reside within nested collections, irrespective of their parent restrictions.\n\nAn exemplary attack request and JSON payload output displays the structural leak of internal documents:\n\njson\n{\n \"meta\": {\n \"total_count\": 1\n },\n \"items\": [\n {\n \"id\": 109,\n \"meta\": {\n \"type\": \"wagtaildocs.Document\",\n \"detail_url\": \"https://example.com/api/v2/documents/109/\",\n \"download_url\": \"/documents/109/q4_merger_strategy_confidential.pdf\"\n },\n \"title\": \"Q4 Merger Strategy Confidential\"\n }\n ]\n}\n\n\nAlthough downloading the file binary from /documents/109/ may prompt an authentication challenge if separate page-level restrictions or document-view middlewares are active, the metadata exposure itself is highly valuable. Attackers learn sensitive titles, structure, and operational classifications, exposing internal activities and business intelligence.

Impact Assessment

The impact of GHSA-C2XX-CJMH-9Q8F is characterized as moderate-severity information disclosure. In enterprise CMS contexts, Wagtail is often used to manage internal intranet wikis, sensitive documentation pipelines, or staging environments for upcoming products. Exposing filenames and project directories reveals proprietary schedules, personal data, and corporate structure.\n\nAccording to the CVSS v3.1 system, this issue receives a base score of 5.3 (Medium). The vector breakdown highlights key parameters: Network vector (AV:N), Low complexity (AC:L), No permissions required (PR:N), No user interaction (UI:N), and Partial Confidentiality impact (C:L) with No integrity (I:N) or availability (A:N) impact.\n\nAlthough there is no current evidence of active, weaponized exploits in public database systems, verification of the issue remains trivial. The vulnerability can be exposed with standard diagnostic tools, putting organizations at risk of passive automated indexing if their endpoints remain open to the public internet.

Remediation and Mitigation Guidance

The primary remediation path is upgrading the Wagtail core package to the designated secure versions. Maintainers have backported patches across all active release branches. For deployments utilizing the 7.0 series, upgrade to 7.0.9. Deployments on versions 7.1 through 7.3 must update to 7.3.4. For installations running 7.4, upgrade to 7.4.3. Implementations on the 8.0 release candidate series must transition to 8.0rc2.\n\nIf upgrading immediately is not technically feasible due to dependency lockups, administrators can implement a coding workaround. Overriding the default API viewsets inside the API router configuration allows engineers to enforce Django Rest Framework authentication permission classes. Requiring authentication blocks anonymous client enumeration entirely.\n\npython\n# Configuration workaround in api.py\nfrom wagtail.api.v2.router import WagtailAPIRouter\nfrom wagtail.images.api.v2.views import ImagesAPIViewSet\nfrom rest_framework.permissions import IsAuthenticated\n\nclass SecuredImagesAPIViewSet(ImagesAPIViewSet):\n # Restrict endpoint to authenticated users only\n permission_classes = [IsAuthenticated]\n\napi_router = WagtailAPIRouter('wagtailapi')\napi_router.register_endpoint('images', SecuredImagesAPIViewSet)\n\n\nAlternatively, security teams can implement traffic filtration policies on their reverse proxies or Web Application Firewalls (WAF). By configuring rules that block external access to /api/v2/images/ and /api/v2/documents/ while permitting access only to trusted internal microservices, the exposure window is completely closed until application-level patches are deployed.

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Affected Systems

Wagtail CMS Documents API V2Wagtail CMS Images API V2

Affected Versions Detail

Product
Affected Versions
Fixed Version
wagtail
Wagtail
< 7.0.97.0.9
wagtail
Wagtail
>= 7.1, < 7.3.47.3.4
wagtail
Wagtail
>= 7.4, < 7.4.37.4.3
wagtail
Wagtail
>= 8.0rc1, < 8.0rc28.0rc2
AttributeDetail
CWE IDCWE-200 / CWE-284 / CWE-276
Attack VectorNetwork
CVSS v3.15.3 (Medium)
Exploit StatusNone / Unproven
KEV StatusNot Listed
ImpactInformation Disclosure (Metadata Leakage)

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1592Gather Victim Host Information
Reconnaissance
CWE-200
Exposure of Sensitive Information to an Unauthorized Actor

The product exposes sensitive information to an actor who is not authorized to have access to that information.

Vulnerability Timeline

Vulnerability discovered and reported by security researcher Ta Duc Thien
2026-08-20
Wagtail security advisory GHSA-c2xx-cjmh-9q8f is officially published
2026-08-20
Wagtail releases patch versions 7.0.9, 7.3.4, 7.4.3, and 8.0rc2 to resolve the issue
2026-08-20

References & Sources

  • [1]GitHub Security Advisory: GHSA-c2xx-cjmh-9q8f
  • [2]Wagtail CMS GitHub Repository
  • [3]Wagtail 7.0.9 Release Notes
  • [4]Wagtail 7.3.4 Release Notes
  • [5]Wagtail 7.4.3 Release Notes

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•2 minutes ago•CVE-2026-109619
9.2

CVE-2026-109619: Remote Code Execution in PHP Core via Stale Global State Memory Corruption (PHP2Shell)

CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.

Alon Barad
Alon Barad
1 views•6 min read
•5 minutes ago•CVE-2026-113721
4.5

CVE-2026-113721: Unsafe Link Resolution in virtualenv File Generation

In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.

Amit Schendel
Amit Schendel
1 views•5 min read
•9 days ago•CVE-2026-87697
8.8

CVE-2026-87697: Untrusted Deserialization in .NET PresentationCore Clipboard Handling

A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.

Alon Barad
Alon Barad
31 views•5 min read
•9 days ago•CVE-2026-70007
8.8

CVE-2026-70007: Out-of-Bounds Write Vulnerability in .NET Framework and WPF Subsystem

An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.

Amit Schendel
Amit Schendel
19 views•6 min read
•10 days ago•CVE-2026-70186
7.5

CVE-2026-70186: ASP.NET Core Denial of Service Vulnerability via Framework Deadlock

ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.

Amit Schendel
Amit Schendel
18 views•5 min read
•10 days ago•CVE-2026-70035
8.8

CVE-2026-70035: Insecure Deserialization Remote Code Execution in Microsoft .NET Framework and .NET Runtime

CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.

Amit Schendel
Amit Schendel
24 views•6 min read