Feb 19, 2026·5 min read·32 visits
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.
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 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 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 objPreviously, 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.
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:
/screenshots/1001.png, /screenshots/1002.png), it's game over. A simple curl loop will scrape the entire database.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.
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.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Weblate WeblateOrg | < 5.15.2 | 5.15.2 |
| Attribute | Detail |
|---|---|
| CWE | CWE-284 (Improper Access Control) |
| CVSS v3.1 | 7.5 (High) |
| Attack Vector | Network |
| Privileges Required | None |
| Fix Version | 5.15.2 |
| Likelihood | Low (Requires URL prediction) |
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.
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.
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.
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.
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.
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.