Sep 25, 2026·7 min read·21 visits
Unsafe path resolution in knowns < 0.30.0 allows remote users with low privileges to read, write, and delete arbitrary markdown files on the server.
A critical path traversal vulnerability (CWE-22) exists in knowns prior to version 0.30.0. The software fails to restrict file path arguments passed to Model Context Protocol (MCP) tools, permitting low-privilege users to escape the designated base storage directories and manipulate arbitrary markdown files on the host filesystem.
The knowns open-source project is a utility environment designed for managing documentation and memory layers. It incorporates a Model Context Protocol (MCP) interface that allows external agents and tools to interact with local markdown-based storage. The primary attack surface resides in the MCP storage APIs, specifically within the docs and memory namespaces. These APIs expose endpoints intended to create, read, update, and delete documentation or memory records within predefined base directories.
In versions of knowns preceding 0.30.0, input path parameters provided to the document and memory handlers were processed without adequate validation boundaries. An attacker capable of sending low-privilege commands to the MCP server could exploit this lack of sanitization. By supplying path strings containing directory traversal sequences, the attacker could escape the designated workspace base directories.
The underlying bug class is a classic Directory Traversal vulnerability (CWE-22). The application relies on the standard library file functions of the Go language without evaluating whether resolved paths cross physical system boundaries. This flaw exposes sensitive operational documentation and markdown logs. In addition, the docs.update implementation introduced an authorization bypass (CWE-863) because it allowed rename operations that could delete arbitrary destination files.
The technical root cause of this vulnerability lies in the implementation of the filepath.Join function within Go's standard library. The standard filepath.Join utility is designed to concatenate multiple path elements and subsequently run filepath.Clean on the result. While filepath.Clean simplifies the path by removing redundant directory separators and processing relative hops like ../, it does not restrict the output path to the designated base parent folder.
To illustrate this behavior, consider a scenario where the application concatenates a legitimate base path such as /app/data/docs with an untrusted parameter like ../../../etc/passwd. The filepath.Join invocation evaluates the relative dot-dot segments sequentially. Because no containment verification is performed after path resolution, the clean function resolves the final absolute path to /etc/passwd. The application subsequently passes this resolved path to filesystem APIs like os.ReadFile or os.WriteFile.
In the knowns document storage module, specifically DocStore, the incoming path parameter underwent minimal sanitization before evaluation. The application attempted to normalize paths by stripping leading slashes and trailing extension markers using strings.TrimPrefix(path, "/") and strings.TrimSuffix(path, ".md"). However, it left inner and trailing directory traversal sequences completely unmanaged.
A similar vulnerability pattern affected the memory engine. In MemoryStore.GetInLayer, the identifier id was directly passed to MemoryFileName(id), which concatenated the prefix memory- and suffix .md. When an attacker supplied an identifier such as ../../escape/compromise, the final target resolved to dir/memory-../../escape/compromise.md. This pattern successfully traversed outside the targeted memory folder, resulting in unconstrained filesystem interaction.
Here is a visual model of the vulnerable resolution process:
Prior to the mitigation patch, the file generation path in internal/storage/doc_store.go was structured as follows:
// Vulnerable path resolution logic
path = strings.TrimPrefix(path, "/")
path = strings.TrimSuffix(path, ".md")
absPath := filepath.Join(ds.docsDir(), filepath.FromSlash(path)+".md")This code illustrates the complete trust placed in the untrusted path parameter. Since the code does not assess the prefix of absPath against ds.docsDir(), any traversal sequence is executed without error.
The vulnerability was corrected in commit 09c5a96fd5817b941dc86669278c1a17db10ed4e by introducing a custom path containment solver called safepath. The safepath.resolve function normalizes all incoming paths, converting backslashes to forward slashes to prevent Windows-specific bypasses. It also explicitly filters drive-letter prefixes and Windows device namespace patterns.
The heart of the fix lies in explicit containment verification using filepath.Rel and symlink validation. The safepath package implements the following validation sequence:
// Safe validation implementation inside safepath.go
for _, segment := range strings.Split(normalized, "/") {
if segment == ".." {
return "", fmt.Errorf("path must not contain parent traversal")
}
}
// ...
if err := requireWithin(rootAbs, candidate); err != nil {
return "", err
}By splitting the normalized path and explicitly rejecting any segment containing .., the library blocks standard traversal vectors. It also calculates the relative path between the root and candidate folders, returning an error if the path initiates a directory escape.
Evaluating the completeness of this patch reveals a high level of resilience. The implementation prevents relative directory jumps and includes defensive logic to block alternate data streams on Windows platforms. However, certain theoretical edge-cases persist. In filesystems that are case-insensitive but case-preserving, minor discrepancies can exist depending on operating system configuration. Additionally, non-atomic directory changes (TOCTOU) during symlink resolution represent a residual vector in environments with highly concurrent, unprivileged filesystem access.
Exploitation of CVE-2026-86439 requires an attacker to interact with the exposed MCP server tools. The attacker must possess sufficient permissions to execute basic document or memory operations, which are typically low-privilege. Once authorized, the attacker constructs a structured JSON payload targeting one of the vulnerable endpoints, such as docs.get or docs.create.
To read a markdown file outside the workspace root, the attacker inserts directory traversal elements into the path field. The payload is sent via the MCP interface:
{
"path": "../../../system_configuration"
}The server processes the payload, cleans the path to resolve to a location outside the base directory, and fetches the file contents.
The exploitability of this flaw is demonstrated by official test cases introduced during patch development. The developer implemented TestDocStoreRejectsTraversalAndSymlinkEscape to verify that attempts to construct paths like ../outside or /tmp/outside are blocked by the safety layer. Similarly, TestMemoryStoreRejectsUnsafeIDs confirms that arbitrary memory identifiers are parsed against a strict regular expression to block platform-specific escapes.
The operational impact of this path traversal vulnerability is significant. An attacker can read, write, update, and delete arbitrary markdown files on the host filesystem, subject to the permissions of the user account executing the knowns service. If the server runs with administrative privileges, this access can lead to the exposure of configuration data, environment variables, or critical cryptographic assets stored in markdown format.
The security posture is further weakened by the interaction with docs.update. In previous versions, the rename functionality of update operations was governed solely by the CapWrite capability instead of the explicit CapDelete capability. Consequently, an attacker could abuse the update flow to overwrite or relocate files, causing a logical deletion of files on the target filesystem. This behavior maps directly to CWE-863 (Incorrect Authorization).
The CVSS v3.1 base score of 8.8 reflects the high severity of the vulnerability. The low-complexity attack path, combined with network-level delivery, allows remote exploitation with minimal prerequisite privileges. Although the scope remains unchanged, the complete loss of confidentiality, integrity, and availability within the markdown workspace creates a high-risk scenario for affected enterprise deployments.
Remediation of CVE-2026-86439 requires upgrading all active installations of the knowns project to version 0.30.0 or higher. This release integrates the validation logic provided by the safepath engine. Prior to upgrading, administrators should identify all current service instances and evaluate their configuration layers.
If immediate patching is not feasible, organizations must implement temporary workarounds to mitigate exposure. The primary mitigation strategy involves restricting the operational permissions of the running process. The knowns binary must execute under a dedicated, low-privilege service account configured with minimal read and write access to the host operating system.
Network-level access controls should also be deployed to protect the MCP server endpoint. Restricting access to authorized API consumers or placing the server behind an authenticated reverse proxy limits the attack vector. Furthermore, intrusion detection rules should monitor for traversal payloads such as ../ and ..\ within HTTP payloads or JSON-RPC tool parameters directed at the MCP endpoints.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
knowns knowns-dev | < 0.30.0 | 0.30.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Secondary CWE ID | CWE-863 |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.8 |
| EPSS Score | 0.01079 (1.08%) |
| Exploit Status | Proof of Concept Available |
| CISA KEV Status | Not Listed |
The application uses external input to construct a pathname that is intended to be within a restricted directory, but it does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location outside of the restricted directory.
FileGator versions prior to 7.15.0 contain a missing authorization check (CWE-862) and predictable identifier generation flaw (CWE-330) in the batch download implementation. When a user initiates a batch download, FileGator generates a temporary ZIP archive identified by PHP's non-cryptographic uniqid() function without binding the resulting identifier to the creating user's session. Consequently, any authenticated user with read, download, and batchdownload permissions who obtains or predicts an active archive identifier can retrieve another user's private files via GET /batchdownload, bypassing per-user home directory isolation and deleting the victim's temporary archive upon download completion.
An authorization bypass and insecure direct object reference (IDOR) vulnerability exists in FileGator versions prior to 7.15.0 within the chunked file upload reassembly handler. When processing multipart uploads in backend/Controllers/UploadController.php, the application fails to namespace the target assembly filename with a user-specific prefix inside the shared temporary storage directory. Authenticated users with upload privileges can manipulate chunk metadata parameters to exfiltrate, corrupt, or delete arbitrary transient files belonging to other users or the system.
CVE-2026-77596 is an authorization bypass vulnerability in the Kubeflow Pipelines API server affecting multi-user deployments prior to version 2.18.0. The HTTP multipart upload handlers prematurely terminate authorization checks and return success when the target namespace parameter is empty or omitted. Because the default configuration allows pipelines without namespaces to function as cluster-wide shared resources, any low-privileged tenant can create shared pipelines or inject arbitrary pipeline versions into existing shared pipelines without undergoing Kubernetes SubjectAccessReview validation. When other tenants execute unpinned recurring runs tracking these shared pipelines, the attacker-supplied workload runs inside the victim tenant's namespace using the victim's service account credentials.
An authorization bypass vulnerability in Velocidex Velociraptor versions prior to 0.77.2 allows authenticated users with low-privilege query permissions to bypass access controls in the sql() VQL plugin. By supplying crafted MySQL connection strings pointing to an attacker-controlled rogue MySQL server with local-infile enabled, an attacker can read arbitrary files from the Velociraptor server host filesystem with the privileges of the server process.
CVE-2026-97705 (GHSA-h89v-g948-47vp) is a high-severity unauthenticated Denial of Service (DoS) vulnerability affecting the Moleculer microservices framework for Node.js in versions prior to 0.14.36 and 0.15.2. The vulnerability resides in the internal TCP transporter packet parser (`src/transporters/tcp/parser.js`), which decodes the 4-byte packet length field as a signed 32-bit integer using `Buffer.prototype.readInt32BE()`. An unauthenticated attacker with network access to an exposed TCP transporter port can transmit a single malformed packet containing a negative length value or a positive length value less than the 6-byte header size. Due to how Node.js `Buffer.prototype.slice()` processes negative or sub-header offsets, the parser fails to advance the incoming buffer cursor while remaining inside a synchronous `while (packet.length > 0)` loop. Because Node.js relies on a single-threaded event loop, this infinite loop permanently blocks execution, freezing all services and endpoints within the affected process until manual intervention.
CVE-2026-108262 (GHSA-9hq4-hm3j-jmph) is a path traversal and arbitrary file overwrite vulnerability in the tar archive extraction routine of DDEV versions 1.25.2 and 1.25.3. Resulting from an incomplete fix for CVE-2026-32885, the Untar function in pkg/archive/archive.go validates absolute symbolic link targets by rebasing them against the extraction destination directory, but subsequently creates the symbolic link on disk using the raw, unvalidated absolute path. When subsequent entries in the archive write through the planted symbolic link, the host operating system resolves the link directly to the host filesystem, allowing an attacker to overwrite arbitrary files with the privileges of the user executing DDEV.