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-92HV-J533-69WC

GHSA-92HV-J533-69WC: Information Disclosure via ETag Conditional Matching in Wagtail CMS

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 21, 2026·7 min read·2 visits

Executive Summary (TL;DR)

Wagtail CMS evaluates HTTP ETag headers before enforcing authentication and authorization checks on document serve views, leaking whether specific documents match guessed SHA-1 hashes.

An information disclosure vulnerability in the document serving subsystem of Wagtail CMS allows unauthorized users to verify if private documents match guessed SHA-1 hashes due to improper order of authentication checks.

Vulnerability Overview

Wagtail CMS contains a document management subsystem that allows administrators and content creators to upload, manage, and serve files securely. This subsystem controls access to documents using permissions, group access restrictions, and password protection schemes to prevent unauthorized viewing of sensitive files. The default document-serving implementation relies on a central view to parse incoming document requests and verify whether the requesting user possesses the requisite privileges to download the resource.

The vulnerability within this subsystem is classified as CWE-280: Improper Handling of Insufficient Permissions or Privileges. It emerges from the system utilizing standard HTTP ETag header validation before verifying whether the user is authorized to access the file. The vulnerability exposes an information disclosure vector, functioning as a binary verification oracle that confirms whether a specific document has a given SHA-1 hash.

Because the request processing pipeline evaluates the document's file hash early, it exposes structural information. This order-of-operations security flaw bypasses access control mechanisms entirely under specific conditions. Security researchers and operators must understand the execution flow to identify where the logic breaks down inside the application framework.

Root Cause Analysis

To optimize bandwidth usage and reduce server load, Wagtail utilizes HTTP ETags for conditional caching. In Django applications, this is typically handled by the @etag decorator, which intercepts incoming HTTP GET requests containing validation headers such as If-None-Match or If-Match. The decorator executes an auxiliary database query to determine the file hash of the requested resource before executing the primary view function.

If the client-provided header matches the database-retrieved SHA-1 hash, Django halts further processing and immediately returns an HTTP 304 Not Modified status code. If the hashes do not match, Django passes execution to the target view function, which then runs security checks. Since the security and authentication checks reside entirely inside the view function rather than a pre-execution middleware layer, the HTTP status code differs based on whether the guessed hash is correct.

An unauthorized user can exploit this logical sequencing flaw. By submitting a request with a guessed hash, the user receives an HTTP 304 if the guess is correct, and an HTTP 302 or 403 if the guess is incorrect. This differential response behavior allows an attacker to systematically verify the presence and content of files on the system without authorization.

Code Analysis

In vulnerable versions of Wagtail, the serve view in wagtail/documents/views/serve.py is directly decorated with @etag(document_etag). The document_etag utility function executes a database query to retrieve the document hash using the document_id. This evaluation occurs before the permission checks are executed within the body of the serve function, leaving the validation step entirely bypassed in the matching branch.

# Vulnerable implementation
def document_etag(request, document_id, document_filename):
    Document = get_document_model()
    if hasattr(Document, "file_hash"):
        return (
            Document.objects.filter(id=document_id)
            .values_list("file_hash", flat=True)
            .first()
        )
 
@etag(document_etag)
def serve(request, document_id, document_filename):
    Document = get_document_model()
    doc = get_object_or_404(Document, id=document_id)
    # Authentication and permission checks occur below this point

The security patch, applied in commit 4f57d589dd81dca4306b5d45a7dce34c61087966, resolves the vulnerability by restructuring how the @etag decorator is evaluated. The patch removes the global decorator from the serve view. Instead, it defines an inner function named serve_local which is wrapped in @etag(get_etag). This inner function is executed only after all authentication, group access, and password validation checks have succeeded.

# Patched implementation (simplified excerpt)
def serve(request, document_id, document_filename):
    Document = get_document_model()
    doc = get_object_or_404(Document, id=document_id)
    # All authentication and permission checks are executed here first
 
    def get_etag(request):
        try:
            return doc.file_hash
        except AttributeError:
            return None
 
    @etag(get_etag)
    def serve_local(request):
        # File serving logic runs here
        return response
 
    return serve_local(request)

This code restructuring ensures that unauthorized requests are terminated during the initial execution of serve(), returning a redirect or permission-denied response before the serve_local inner function is invoked. Consequently, the conditional ETag evaluation is never executed for unauthorized requests, resolving the information disclosure vector.

Exploitation

To exploit this vulnerability, an attacker must identify the URL path of the document serving endpoint on the target Wagtail site. The default path pattern follows the structure /documents/<document_id>/<filename>. Since document IDs are typically sequential integers, an attacker can iterate through IDs to discover document records.

The attacker must construct a list of target SHA-1 file hashes. This list can include hashes of standard corporate templates, leaked files, known public forms, or software release binaries. The attacker sends a crafted HTTP GET request containing the targeted SHA-1 hash within the If-None-Match header.

If the server returns an HTTP 304 Not Modified status code, the attacker successfully confirms that the document with the targeted ID matches the specified SHA-1 hash. If the server returns an HTTP 302 Found (redirect to login) or HTTP 403 Forbidden response, the attacker knows that the document does not match the specified hash. Repeating this process with multiple candidate hashes allows an attacker to identify the precise contents of private files.

Impact Assessment

The direct technical consequence of this vulnerability is information disclosure. While it does not allow an attacker to read arbitrary contents of private files directly, it serves as a validation mechanism to confirm the presence of known documents. This exposure is critical if attackers seek to verify whether proprietary designs, confidential contracts, or legal agreements have been stored within a private library.

The CVSS v3.1 score is evaluated at 3.7 (Low Severity) with the vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N. The attack complexity is categorized as high because the attacker must have a pre-existing list of candidate SHA-1 hashes to test against the endpoint. The confidentiality impact is rated as low because file contents are not directly extracted.

From a regulatory compliance perspective, this flaw can violate data privacy standards such as GDPR or HIPAA if private records can be identified. Confirming the presence of specific medical or financial records using known hashes constitutes a privacy breach. Therefore, security teams should treat this finding with appropriate urgency despite its low CVSS score.

Remediation

The primary remediation for this vulnerability is upgrading the Wagtail installation to a patched version. Development teams should identify the current branch of Wagtail deployed in their environments and update to version 7.0.9, 7.3.4, 7.4.3, or 8.0rc2, depending on the release branch. Upgrading ensures that the secure deferred ETag evaluation mechanism is enforced globally.

For organizations unable to immediately deploy software updates, temporary mitigations can be implemented at the network edge. Reverse proxies, load balancers, or Web Application Firewalls (WAFs) can be configured to strip the If-Match and If-None-Match HTTP headers from all requests routed to the /documents/ URL pattern. This prevents the upstream Django application from processing conditional ETags, forcing the view to run the permission checks first and return standard redirects.

Additionally, administrators can implement custom middleware to sanitise incoming requests or monitor application logs for anomalous traffic. A sudden spike in HTTP requests directed at sequential document IDs containing diverse If-None-Match header values indicates brute-force scanning activity. This scanning behavior can be detected and blocked using automated rate-limiting solutions.

Official Patches

WagtailOfficial Security Advisory

Fix Analysis (1)

Technical Appendix

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

Affected Systems

Wagtail CMS

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.0rc18.0rc2
AttributeDetail
CWE IDCWE-280
Attack VectorNetwork
CVSS v3.13.7 (Low)
Vulnerability TypeInformation Disclosure
Exploit StatusProof of Concept
Componentwagtail/documents/views/serve.py

MITRE ATT&CK Mapping

T1082System Information Discovery
Discovery
T1518Software Discovery
Discovery
CWE-280
Improper Handling of Insufficient Permissions or Privileges

The application does not properly handle cases where an actor has insufficient permissions, allowing execution of critical operations before security validation occurs.

Vulnerability Timeline

Security Patch Authored
2026-08-05
Security Patch Committed to Main Branch
2026-08-20
Advisory GHSA-92hv-j533-69wc Published
2026-08-20

References & Sources

  • [1]GitHub Security Advisory GHSA-92HV-J533-69WC
  • [2]Wagtail Project Security Advisory
  • [3]Wagtail CMS Main Source Code Repository

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

•10 minutes ago•GHSA-P2CH-C2C3-4XM5
8.8

GHSA-P2CH-C2C3-4XM5: Cross-Site Request Forgery in Winter CMS AJAX Routing

Winter CMS contains a routing bypass vulnerability that allows Cross-Site Request Forgery (CSRF) attacks to trigger administrative AJAX handlers. Due to case-insensitivity in PHP's method resolution and an insufficiently strict check in the backend controller system, an attacker can invoke these handler methods through lowercase HTTP GET requests, bypassing default CSRF token validation.

Amit Schendel
Amit Schendel
0 views•4 min read
•about 1 hour ago•GHSA-HQ84-X37P-J6Q5
6.1

GHSA-HQ84-X37P-J6Q5: Reflected Cross-Site Scripting in Winter CMS Backend Table Widget

A reflected Cross-Site Scripting (XSS) vulnerability exists in the backend Table widget of Winter CMS. The vulnerability is located within the search input template partial, where the application retrieves raw user inputs from the query parameters and renders them directly inside a raw-text script container without sanitization. An attacker can exploit this behavior by passing a crafted tag containing raw-text terminators, leading to code execution in the context of the victim's session.

Amit Schendel
Amit Schendel
1 views•5 min read
•about 3 hours ago•GHSA-C2XX-CJMH-9Q8F
5.3

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

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.

Amit Schendel
Amit Schendel
1 views•6 min read
•about 4 hours ago•GHSA-X5CX-W6P2-MXF2
6.5

GHSA-X5CX-W6P2-MXF2: Improper Permission Handling in Wagtail Snippet Copy Functionality

An authorization bypass vulnerability in Wagtail CMS allows authenticated users with snippet creation privileges ('add') to access and view the contents of restricted snippet instances for which they lack viewing or editing permissions. By invoking the copy endpoint, the application pre-populates form data with the properties of the source snippet, exposing sensitive information to unauthorized users.

Alon Barad
Alon Barad
4 views•6 min read
•about 9 hours ago•GHSA-JM5P-837G-RV8G
6.5

GHSA-JM5P-837G-RV8G: Insecure Direct Object Reference (IDOR) in Wagtail Page Translation Endpoint

An authenticated user with global translation permissions can exploit a missing authorization check on the page translation endpoint in Wagtail CMS. This allows the attacker to copy and view pages they do not have explicit edit or explore access to.

Alon Barad
Alon Barad
4 views•7 min read
•about 10 hours ago•CVE-2026-67447
5.3

CVE-2026-67447: Unbounded Memory Allocation leading to Denial of Service in Mailpit SMTP Server

An uncontrolled resource allocation vulnerability (CWE-770) affects Mailpit SMTP server versions 1.30.0 through 1.30.4. The vulnerability is located within the DATA parsing logic, where an unauthenticated remote attacker can stream an endless sequence of bytes devoid of newline characters. Because line size limits are evaluated only after buffer completion, the Go runtime repeatedly allocates memory on the heap to store the single oversized line, causing resource exhaustion and an Out-Of-Memory termination of the service process.

Amit Schendel
Amit Schendel
2 views•8 min read