Skip to content

Commit 863100c

Browse files
committed
fix MCP server path validation security issue (0.3.26)
1 parent 1cbcee5 commit 863100c

4 files changed

Lines changed: 13 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases)
44

5+
## 0.3.26 (2026-04-10)
6+
7+
- Fix: MCP server no longer uses a circular path validation when loading a graph outside cwd — now validates the path exists and ends in `.json` instead of checking containment within its own parent directory (security fix)
8+
59
## 0.3.25 (2026-04-09)
610

711
- Fix: `graphify install --platform gemini` now routes to `gemini_install()` instead of erroring — `gemini` was missing from `_PLATFORM_CONFIG` (#171)

graphify/serve.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
from pathlib import Path
66
import networkx as nx
77
from networkx.readwrite import json_graph
8-
from graphify.security import validate_graph_path, sanitize_label
8+
from graphify.security import sanitize_label
99

1010

1111
def _load_graph(graph_path: str) -> nx.Graph:
1212
try:
13-
safe = validate_graph_path(graph_path, base=Path(graph_path).resolve().parent)
13+
resolved = Path(graph_path).resolve()
14+
if resolved.suffix != ".json":
15+
raise ValueError(f"Graph path must be a .json file, got: {graph_path!r}")
16+
if not resolved.exists():
17+
raise FileNotFoundError(f"Graph file not found: {resolved}")
18+
safe = resolved
1419
data = json.loads(safe.read_text())
1520
try:
1621
return json_graph.node_link_graph(data, edges="links")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "graphifyy"
7-
version = "0.3.25"
7+
version = "0.3.26"
88
description = "AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, OpenClaw, Factory Droid, Trae) - turn any folder of code, docs, papers, or images into a queryable knowledge graph"
99
readme = "README.md"
1010
license = { file = "LICENSE" }

tests/test_serve.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,11 @@ def test_subgraph_to_text_edge_included():
138138
# --- _load_graph ---
139139

140140
def test_load_graph_roundtrip(tmp_path):
141-
from unittest.mock import patch
142141
G = _make_graph()
143142
data = json_graph.node_link_data(G, edges="links")
144143
p = tmp_path / "graph.json"
145144
p.write_text(json.dumps(data))
146-
# validate_graph_path is tested separately; here we test parse correctness
147-
with patch("graphify.serve.validate_graph_path", return_value=p):
148-
G2 = _load_graph(str(p))
145+
G2 = _load_graph(str(p))
149146
assert G2.number_of_nodes() == G.number_of_nodes()
150147
assert G2.number_of_edges() == G.number_of_edges()
151148

0 commit comments

Comments
 (0)