CodeVetter · Repo Unpack · Risk map
ggml-org/llama.cpp
Biggest risks: server-side command execution features (exec_shell_command, MCP stdio subprocesses, router child spawning, CORS proxy) which are opt-in but powerful; unauthenticated-by-default HTTP API; remote content trust (HF downloads, remote presets, prebuilt UI assets); and a very large single-threaded decode loop in server-context.cpp (~5.5k lines) where a fatal error aborts all slots. GGML_ABORT/GGML_ASSERT turn many error paths into crashes rather than graceful failures.
- exec_shell_command is a built-in server tool that runs arbitrary shell commands via run_subprocess (sheredom subprocess.h, subprocess_option_search_user_path|inherit_environment); an 'isolate' mode can redirect file/exec ops through a container or remote host transport — gated behind --tools/--tools-runtime which the server logs as experimental security warnings.
- MCP integration spawns arbitrary configured commands as stdio subprocesses (server_mcp_stdio wraps common_subproc) with ndjson JSON-RPC over stdin/stdout; MCP server configs can be supplied as JSON including Cursor 'mcpServers' format.
- Router mode spawns child llama-server processes with attacker-influenceable args (model params come from HTTP /models/load requests); it requires LLAMA_SUBPROCESS and throws when subprocess support is compiled out.
- Auth is optional: API keys come from --api-key/--api-key-file (LLAMA_ARG_API_KEY env); the server only warns (not fails) when cors_origins='*' with no keys, and prints 'do not expose to untrusted environments' warnings for router/tools/MCP features.
- A /cors-proxy endpoint proxies arbitrary GET/POST requests when --ui-mcp-proxy is enabled (experimental, used by the Web UI for MCP), effectively an open proxy surface on the server port.
- Remote model handling trusts network content: -hf downloads GGUFs and preset .ini files from HF (with an explicit 'only use presets that you can trust' warning), and LLAMA_USE_PREBUILT_UI pulls UI assets from a HF bucket at build time.
- `llama update` shells out: on LLAMA_INSTALL_BUILD it runs system('curl ... | sh') or powershell irm|iex against https://llama.app — a code-execution path dependent on TLS and remote server integrity.
- Error handling frequently escalates to process abort: GGML_ABORT/GGML_ASSERT appear on hot paths (e.g. >3 consecutive empty decode batches aborts; model not implementing llama_model_base aborts), so malformed inputs or edge states can take down the whole server rather than one request.
- Decode failure blast radius: when llama_decode returns nonzero, decode() sends errors to ALL processing slots and clears the entire context per-slot ('it's complicated to keep track of how much of the current batch has been processed'), so one bad request can kill concurrent sessions.
- server-context.cpp is a 5,558-line pimpl monolith owning slots, batching, checkpointing, prompt cache, metrics, LoRA, speculative decode and all route handlers — high coupling makes regressions likely; code comments admit 'alora handling is too messy, need to refactor'.
- GGUF/mmap input parsing is a trust boundary: llama_model_loader and gguf.cpp parse arbitrary model files (metadata strings, tensor offsets) and mmap them directly; params.check_tensors exists but untrusted model files remain a memory-safety attack surface. (inferred)
- SSL is optional and off unless CPPHTTPLIB_OPENSSL_SUPPORT is compiled in AND both --ssl-key-file/--ssl-cert-file are given; otherwise the API (including Bearer keys) runs plaintext HTTP — default port :8080 with a pending change to :9931.
- Debug/env side-channels: LLAMA_TRACE, LLAMA_SERVER_SLOTS_DEBUG, LLAMA_SERVER_SLOTS_N_DIFF change runtime behavior; --prompts-log-dir writes every prompt to disk (path_prompts_log_dir); prompts are also logged at debug level.