Hi, great project! I was doing a security review before deploying this as an MCP server against a personal vault, and found a path traversal issue worth flagging.
Location: src/lib/writer.ts — kg_create_node and kg_annotate_node tools
Issue: User-supplied directory and nodeId parameters are passed to path.join() without verifying the resolved absolute path stays within vaultPath. path.join() normalizes paths but does not block escape sequences like ../../.
Impact: A crafted tool call could potentially write files outside the intended vault directory.
Suggested fix:
const absPath = path.resolve(this.vaultPath, directory, filename);
const relative = path.relative(this.vaultPath, absPath);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
throw new Error(`Path escape attempt: ${absPath}`);
}
This check should be applied before any file creation or append operation in VaultWriter.
Hi, great project! I was doing a security review before deploying this as an MCP server against a personal vault, and found a path traversal issue worth flagging.
Location: src/lib/writer.ts — kg_create_node and kg_annotate_node tools
Issue: User-supplied directory and nodeId parameters are passed to path.join() without verifying the resolved absolute path stays within vaultPath. path.join() normalizes paths but does not block escape sequences like ../../.
Impact: A crafted tool call could potentially write files outside the intended vault directory.
Suggested fix:
This check should be applied before any file creation or append operation in VaultWriter.