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



CVE-2026-21889

CVE-2026-21889: Weblate's Candid Camera – Leaking Screenshots via Static Misconfiguration

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 19, 2026·5 min read·32 visits

Executive Summary (TL;DR)

Weblate versions < 5.15.2 served screenshot uploads directly via the web server (Nginx/Apache), bypassing Django's permission checks. Unauthenticated users could view private project screenshots if they could guess the URL. Fixed by routing media requests through a protected Django view.

Weblate, the popular open-source localization tool, suffered from a classic architectural disconnect between application logic and web server configuration. By defaulting to serving the `/media/` directory directly via Nginx or Apache, Weblate inadvertently bypassed its own authentication middleware for uploaded screenshots. This allowed unauthenticated attackers to access sensitive visual context—potentially revealing internal dashboards, PII, or unreleased features—simply by knowing or guessing the file path.

The Hook: Lost in Translation (and Authorization)

Localization is hard. To make it easier, Weblate allows developers to upload screenshots of their application so translators can see exactly where a string like "Submit" appears—is it a button? A modal? A command to launch nuclear missiles?

This context is vital. However, in the world of software development, context is also sensitive. These screenshots often depict unreleased features, internal admin panels, or user interfaces populated with real (and hopefully test) data. You would assume that if a project is marked "Private" in Weblate, the screenshots attached to it are also private.

Well, prior to version 5.15.2, that assumption was dead wrong. It turns out that while Weblate locked the front door (the project dashboard), it left the side window (the media directory) wide open. This vulnerability isn't a complex buffer overflow; it's a fundamental misunderstanding of who is responsible for guarding the assets.

The Flaw: The Static File Trap

The root cause here is a classic "DevOps vs. Dev" conflict. In the Django world (which Weblate is built on), serving static files and user uploads through the Python application is considered slow and inefficient. The standard advice is to let a high-performance web server like Nginx or Apache handle the /media/ directory directly.

Weblate's official documentation and example configurations followed this advice to a fault. They provided Nginx configs that looked like this:

location /media/ {
    alias /home/weblate/data/media/;
    expires 30d;
}

Do you see the problem? When a request hits https://weblate.company.com/media/screenshots/secret_admin_panel.png, Nginx looks at the location block, sees it matches /media/, and happily serves the file from the disk. Nginx does not know what a "Django Session" is. It doesn't care about your Access Control Lists (ACLs) or whether User ID 5 has permission to view Project X. It just serves bytes.

By bypassing the application layer entirely, Weblate inadvertently created a massive IDOR (Insecure Direct Object Reference) scenario, or more accurately, a lack of access control on static assets. The application code checked permissions if you asked the application, but nobody was asking the application.

The Code: Patch Analysis

The fix required a two-pronged approach: changing the code to handle file serving securely, and screaming at administrators to update their web server configs. The code change was introduced in commit a6eb5fd0299780eca286be8ff187dc2d10feec47.

The developers introduced a new view specifically for serving these screenshots. Instead of a direct link to a file, the application now routes the request through a ScreenshotView class.

Here is the logic that was missing:

# Inside weblate/trans/views/files.py
 
class ScreenshotView(DetailView):
    # ... setup code ...
    
    def get_object(self, *args, **kwargs):
        obj = super().get_object(*args, **kwargs)
        # The Critical Fix:
        # Verify the user has access to the component this screenshot belongs to.
        self.request.user.check_access_component(obj.translation.component)
        return obj

Previously, this logic didn't exist because the request never reached Python. Now, the view explicitly checks check_access_component. If the user doesn't have rights to the component, they get a 403 Forbidden, not a PNG of your CEO's password hint.

The Exploit: Doomscrolling the Media Directory

Exploiting this is trivially easy if you know the file paths, and moderately annoying if you don't. Since directory listing is usually disabled in Nginx/Apache by default (hopefully), an attacker can't just browse the directory tree like an FTP server.

However, filenames in Weblate might be predictable or leaked via other channels. For example:

  1. Metadata Leakage: An attacker with access to a public component might query the API and see how screenshot URLs are structured. If they are sequential IDs (/screenshots/1001.png, /screenshots/1002.png), it's game over. A simple curl loop will scrape the entire database.
  2. Hash Prediction: If filenames are based on hashes of known values (like project names or timestamps), they can be brute-forced.
  3. Client-Side Leaks: Sometimes, a JavaScript bundle or a cached API response might reference a "private" screenshot URL that the frontend intends to hide but still knows about.

Once the attacker has the URL, they simply paste it into their browser. No cookies, no login, no exploit payloads needed. It's the digital equivalent of walking into a bank vault because the door was propped open with a chair.

The Fix: Closing the Blinds

Fixing CVE-2026-21889 is unique because pip install --upgrade weblate is not enough. If you upgrade the application code but leave your Nginx config pointing /media/ to the filesystem, you are still vulnerable.

Step 1: The Upgrade Update Weblate to version 5.15.2 or later. This installs the new ScreenshotView logic capable of verifying permissions.

Step 2: The Config Purge You must edit your web server configuration (Nginx, Apache, etc.). You need to remove any alias or root directive that serves the /media/ directory directly.

For Nginx, delete this block:

# DELETE THIS BLOCK
location /media/ {
    alias /var/lib/weblate/media/;
}

Instead, requests to /media/ should fall through to the default @uwsgi or @proxy block that hands traffic off to the Django application. This ensures the new Python code actually runs for every image request.

Official Patches

WeblateGitHub Commit Fix
WeblateOfficial Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
EPSS Probability
0.04%
Top 87% most exploited

Affected Systems

Weblate < 5.15.2

Affected Versions Detail

Product
Affected Versions
Fixed Version
Weblate
WeblateOrg
< 5.15.25.15.2
AttributeDetail
CWECWE-284 (Improper Access Control)
CVSS v3.17.5 (High)
Attack VectorNetwork
Privileges RequiredNone
Fix Version5.15.2
LikelihoodLow (Requires URL prediction)

MITRE ATT&CK Mapping

T1596Search Open Technical Databases
Reconnaissance
T1213Data from Information Repositories
Collection
CWE-284
Improper Access Control

Vulnerability Timeline

Fix committed to repository
2026-01-06
CVE Published
2026-01-14
Advisory Released
2026-01-14

References & Sources

  • [1]GHSA Advisory
  • [2]NVD CVE Record

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

•29 minutes ago•CVE-2026-68585
5.8

CVE-2026-68585: Metadata Disclosure via Missing Authorization in SiYuan API

A metadata disclosure vulnerability exists in SiYuan prior to version v3.7.3. The /api/block/getBlockInfo endpoint fails to validate authorization boundaries in publish mode, allowing anonymous readers to access private document metadata.

Alon Barad
Alon Barad
0 views•8 min read
•about 1 hour ago•CVE-2026-72812
6.5

CVE-2026-72812: Broken Access Control and SQL Injection in SiYuan

A critical authorization bypass vulnerability exists in SiYuan personal knowledge management system before v3.7.4. The /api/ref/refreshBacklink endpoint lacks administrative role verification, enabling unauthenticated users to initiate database transactions and disk operations. When combined with an unsafe SQL generation pattern in nested backlink queries, an attacker can exploit a secondary SQL injection vulnerability to compromise local databases or cause denial-of-service conditions.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 2 hours ago•CVE-2026-72811
10.0

CVE-2026-72811: Remote SQL Injection in SiYuan Backlink and Mention Search Engine

A critical SQL Injection vulnerability exists in the SiYuan note-taking application (versions <= v3.7.2) due to improper neutralization of single quotes within the backlink and mention search queries. Because the application constructs SQLite Full Text Search (FTS) queries via direct string concatenation and uses a database driver that supports stacked query statements, remote unauthenticated attackers can execute arbitrary SQL commands on the master database, compromising all hosted notebooks. This issue has been fully remediated in version v3.7.4.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 3 hours ago•CVE-2026-72810
8.6

CVE-2026-72810: Publish-Boundary Bypass and Real-Time Data Leakage via WebSocket Session Pollution in SiYuan

CVE-2026-72810 is a critical publish-boundary bypass vulnerability in the SiYuan personal knowledge management system before version 3.7.4. The flaw lies in the backend real-time WebSocket broadcast mechanism. When configured in public publish mode, the system fails to differentiate between unauthenticated public reader sessions and authorized administrative sessions within its global connection pool. This architectural oversight allows unauthenticated remote attackers connecting to the public WebSocket endpoint on port 6808 to passively receive real-time, raw workspace modification events, including keystroke logs, block updates, and content from protected or forbidden documents.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•CVE-2026-72809
8.0

CVE-2026-72809: Authentication Bypass in SiYuan via Localhost Trust Spoofing

An authentication bypass vulnerability exists in the SiYuan personal knowledge management system (versions <= v3.7.2). The flaw occurs because the kernel's authorization validation handler trusts loopback connection origins blindly, allowing remote network attackers to gain administrative privileges via an exposed local reverse proxy.

Alon Barad
Alon Barad
4 views•6 min read
•about 6 hours ago•CVE-2026-72808
6.9

CVE-2026-72808: Unauthorized PDF Annotation Access in SiYuan Knowledge Management System

An information disclosure vulnerability in the SiYuan knowledge management system versions up to and including v3.7.2 allows remote unauthorized attackers to retrieve PDF annotations via the /api/asset/getFileAnnotation endpoint due to missing authorization checks.

Alon Barad
Alon Barad
8 views•6 min read