CVE-2025-61685
Description
Mastra is a Typescript framework for building AI agents and assistants. Versions 0.13.8 through 0.13.20-alpha.0 are vulnerable to a Directory Traversal attack that results in the disclosure of directory listings. The code contains a security check to prevent path traversal for reading file contents, but this check is effectively bypassed by subsequent logic that attempts to find directory suggestions. An attacker can leverage this flaw to list the contents of arbitrary directories on the user's filesystem, including the user's home directory, exposing sensitive information about the file system's structure. This issue is fixed in version 0.13.20.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@mastra/mcp-docs-servernpm | < 0.17.0 | 0.17.0 |
Affected products
1Patches
17f2b528ba82dfix(mcp-docs-server): Differentiate between path not found and path traversal detected (#7648)
2 files changed · +19 −5
.changeset/sharp-clowns-tell.md+5 −0 added@@ -0,0 +1,5 @@ +--- +'@mastra/mcp-docs-server': patch +--- + +Improve security
packages/mcp-docs-server/src/tools/docs.ts+14 −5 modified@@ -6,7 +6,9 @@ import { fromPackageRoot, getMatchingPaths } from '../utils'; const docsBaseDir = fromPackageRoot('.docs/raw/'); -type ReadMdxResult = { found: true; content: string } | { found: false }; +type ReadMdxResult = + | { found: true; content: string; isSecurityViolation: boolean } + | { found: false; isSecurityViolation: boolean }; // Helper function to list contents of a directory async function listDirContents(dirPath: string): Promise<{ dirs: string[]; files: string[] }> { @@ -39,7 +41,7 @@ async function readMdxContent(docPath: string, queryKeywords: string[]): Promise const fullPath = path.resolve(path.join(docsBaseDir, docPath)); if (!fullPath.startsWith(path.resolve(docsBaseDir))) { void logger.error(`Path traversal attempt detected`); - return { found: false }; + return { found: false, isSecurityViolation: true }; } void logger.debug(`Reading MDX content from: ${fullPath}`); @@ -77,17 +79,17 @@ async function readMdxContent(docPath: string, queryKeywords: string[]): Promise const suggestions = ['---', '', contentBasedSuggestions, ''].join('\n'); - return { found: true, content: dirListing + fileContents + suggestions }; + return { found: true, content: dirListing + fileContents + suggestions, isSecurityViolation: false }; } // If it's a file, just read it const content = await fs.readFile(fullPath, 'utf-8'); - return { found: true, content }; + return { found: true, content, isSecurityViolation: false }; } catch (error: any) { void logger.error(`Failed to read MDX content: ${fullPath}`, error); if (error.code === 'ENOENT') { // Only fallback for not found - return { found: false }; + return { found: false, isSecurityViolation: false }; } // Unexpected error: rethrow throw error; @@ -208,6 +210,13 @@ export const docsTool = { error: null, }; } + if (result.isSecurityViolation) { + return { + path, + content: null, + error: 'Invalid path', + }; + } const directorySuggestions = await findNearestDirectory(path, availablePaths); const contentBasedSuggestions = await getMatchingPaths(path, queryKeywords, docsBaseDir); return {
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.