Report privately through GitHub's private vulnerability reporting, which is enabled for this repository: open https://github.com/phbui/gestalt-core/security/advisories/new and describe what you found. Do not open a public issue for a vulnerability. You will get a first reply within 14 days. A fix or a documented workaround follows in the next release, and the advisory is published when the fix lands.
The main branch and the most recent tagged release receive fixes. Older tags do not.
Read this before you install the hooks. Everything below is by design, and each item is a place where a careless setup leaks data or runs code you did not review.
- Notes are an input channel to the agent. The session hooks and the MCP server inject text from
knowledge/into the agent's context. A note written by someone else, or copied from the web, can carry instructions the agent may follow. This is indirect prompt injection, OWASP LLM01 in the OWASP Top 10 for LLM applications, and no filter prevents it fully. Treat notes from other people as untrusted and read them before indexing. - The services do not authenticate. The MCP server's HTTP mode, the embedding shim and every port in
docker-compose.ymlaccept any request that reaches them. The compose file binds its ports to127.0.0.1and the MCP server's HTTP mode binds to127.0.0.1by default. The embedding shim binds the Docker bridge address172.17.0.1by default, which containers on this host reach and the network does not. Keep them there. A browser page can reach a localhost port through DNS rebinding, so the MCP server checks the Host header, and stdio mode, which opens no port, is the safer choice for one user on one machine. - The index build runs pinned model code from Hugging Face. The default embedder,
NovaSearch/stella_en_400M_v5, ships its own modelling code in the model repository, and loading it executes that Python on every version of transformers. The weights and the code are pinned to one revision intools/gestalt_embed_config.py, so a changed upstream file cannot run here without a change to this repository.GESTALT_TRUST_REMOTE_CODE=0forbids remote code, and under it the stella profile does not load. Thenomicprofile loads through thenomic_bertclass that transformers 5.5 and later ship, so on a current install it runs no code from the Hub, and on an older library it falls back to code pinned to one commit ofnomic-ai/nomic-bert-2048. The embedding shim uses the same settings. The first index build also downloads the model, which is the one network call a default install makes. - The stop hook sends session text to Letta. When a Letta server answers at
http://localhost:8283, the stop hook sends up to 800 characters of each message in the session to it, and Letta forwards that text to whatever model its agent is configured with. Nothing is sent when no server answers. Do not run Letta against a remote model if your sessions hold secrets. - The audit hook logs every shell command. Each command the agent runs is appended to
~/.claude/audit.log, secrets included. Protect that file like a shell history, and rotate any secret you typed into a command. - The safety hooks are best-effort guardrails and not a sandbox. They block the destructive commands and the self-edits they recognise. They do not confine the agent, and a command they do not recognise runs. Use the operating system's own sandboxing when you need confinement.
In scope: the hooks under claude-tree/hooks/, the MCP server, the index builder, the command-line search, the evaluation harness and the Docker and systemd files shipped here. Out of scope: Claude Code, Cursor, Letta, Graphiti, FalkorDB, Ollama and the models, which have their own reporting channels.