Skip to content

Security: codehornets/graphify

Security

SECURITY.md

Security Policy

Supported Versions

Version Supported
0.1.x Yes
< 0.1 No

Reporting a Vulnerability

Do not open a public GitHub issue for security vulnerabilities.

Report security issues via GitHub's private vulnerability reporting, or email the maintainer directly. Please include:

  • Description of the vulnerability
  • Steps to reproduce
  • Potential impact
  • Suggested fix (if any)

We will acknowledge receipt within 48 hours and aim to release a fix within 7 days for critical issues.

Security Model

graphify is a local development tool. It runs as a Claude Code skill and optionally as a local MCP stdio server. It makes no network calls during graph analysis - only during ingest (explicit URL fetch by the user).

Threat Surface

Vector Mitigation
SSRF via URL fetch security.validate_url() allows only http and https schemes. Redirect targets are re-validated by _NoFileRedirectHandler - a redirect to file:// is blocked.
Oversized downloads safe_fetch() streams responses and aborts at 50 MB. safe_fetch_text() aborts at 10 MB.
Non-2xx HTTP responses safe_fetch() raises HTTPError on non-2xx status codes - error pages are not silently treated as content.
Path traversal in MCP server security.validate_graph_path() resolves paths and requires them to be inside graphify-out/. Also requires the graphify-out/ directory to exist.
XSS in graph HTML output security.sanitize_label() strips control characters, caps at 256 chars, and HTML-escapes all node labels and edge titles before pyvis embeds them.
Prompt injection via node labels sanitize_label() also applied to MCP text output - node labels from user-controlled source files cannot break the text format returned to agents.
YAML frontmatter injection Newlines stripped from user-provided strings before embedding in YAML frontmatter (e.g. in save_query_result()).
Encoding crashes on source files All tree-sitter byte slices decoded with errors="replace" - non-UTF-8 source files degrade gracefully instead of crashing extraction.
Symlink traversal os.walk(..., followlinks=False) is explicit throughout detect.py.
Corrupted graph.json _load_graph() in serve.py wraps json.JSONDecodeError and prints a clear recovery message instead of crashing.

What graphify does NOT do

  • Does not run a network listener (MCP server communicates over stdio only)
  • Does not execute code from source files (tree-sitter parses ASTs - no eval/exec)
  • Does not use shell=True in any subprocess call
  • Does not store credentials or API keys

Optional network calls

  • ingest subcommand: fetches URLs explicitly provided by the user
  • PDF extraction: reads local files only (pypdf does not make network calls)
  • watch mode: local filesystem events only (watchdog does not make network calls)

There aren’t any published security advisories