Skip to content

fix(mcp): jail LLM source excerpt reads - #151

Closed
tachyon-beep wants to merge 1 commit into
mainfrom
codex/fix-vulnerability-in-mcp-llm-prompts
Closed

fix(mcp): jail LLM source excerpt reads#151
tachyon-beep wants to merge 1 commit into
mainfrom
codex/fix-vulnerability-in-mcp-llm-prompts

Conversation

@tachyon-beep

Copy link
Copy Markdown
Collaborator

Motivation

  • Prevent untrusted catalogue rows from causing confidential local files to be read and included in live LLM prompts by revalidating stored source_file_path values at use time against the canonical project root.
  • Fail closed for outside-project or symlink-escaped paths so an attacker cannot poison a committed catalogue to exfiltrate secrets when MCP is wired to a live provider.

Description

  • Replaced the old SourceExcerptError struct with an enum SourceExcerptError that adds an InvalidPath variant and maps errors to appropriate McpErrorCodes.
  • Added normalize_source_path usage and canonicalization in verified_source_excerpt(project_root, entity) to jail every file read and reject absolute/../symlink-escaped paths outside the project root.
  • Plumbed the new verified_source_excerpt(&self.project_root, &entity) signature through summary and inferred-edge prompt construction (src/tools/summary.rs, src/tools/status.rs) so all LLM prompt paths are validated before reading.
  • Added a regression test summary_cold_miss_refuses_catalogue_path_outside_project that poisons the catalogue with an outside-project source_file_path and asserts the summary call returns an invalid-path envelope and does not invoke the provider.

Testing

  • Ran cargo fmt --all -- --check which succeeded.
  • Ran cargo test -p loomweave-mcp summary_cold_miss_refuses_catalogue_path_outside_project which passed and the new regression test succeeded.
  • Ran the full cargo test -p loomweave-mcp which showed all 124 library tests passed, but one unrelated lifecycle test failed due to a grandchild process timing issue (the failure is unrelated to the code changes and is preserved as observed).
  • Verified git diff --check and formatting diffs were clean.

Codex Task

Copilot AI lite review requested due to automatic review settings September 1, 2026 18:59
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens loomweave-mcp against prompt-time local file exfiltration by re-validating stored source_file_path values at use time, ensuring they cannot escape the project root (including via symlinks), and surfacing a stable invalid-path MCP error when validation fails.

Changes:

  • Introduces an enum SourceExcerptError with an InvalidPath variant and maps excerpt failures to appropriate McpErrorCodes.
  • Jails source excerpt reads by normalizing/canonicalizing paths against the canonical project root before reading file contents.
  • Adds a regression test that poisons the catalogue with an outside-project path and asserts the tool fails with invalid-path and does not invoke the LLM provider.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
crates/loomweave-mcp/src/lib.rs Adds InvalidPath error variant and applies normalize_source_path when building source excerpts to prevent out-of-root reads.
crates/loomweave-mcp/src/tools/summary.rs Plumbs project_root through summary + inferred-edge prompt construction so excerpt reads are jailed.
crates/loomweave-mcp/src/tools/status.rs Ensures token-estimation path for summaries uses the jailed excerpt read.
crates/loomweave-mcp/tests/storage_tools.rs Adds a regression test asserting outside-project catalogue paths fail closed with invalid-path and no provider invocation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +5633 to +5636
let path =
normalize_source_path(project_root, path).map_err(|_| SourceExcerptError::InvalidPath {
entity_id: entity.id.clone(),
})?;
@tachyon-beep

Copy link
Copy Markdown
Collaborator Author

Superseded by the rebase onto release/1.6.0 (the working release branch) — same commit, landing there.

@tachyon-beep
tachyon-beep deleted the codex/fix-vulnerability-in-mcp-llm-prompts branch September 1, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants