Why this verdict
mcp-server . Suspicious
- inconclusive: gap no_tools_extracted at pyproject.toml
mcp-server ugs_mcp Suspicious
- suspicious: finding mcp-server:ugs_mcp:ugs_mcp/server.py:51:PRIVESC
- suspicious: finding mcp-server:ugs_mcp:ugs_mcp/tools/inspector.py:60:DESTRUCT
- suspicious: finding mcp-server:ugs_mcp:ugs_mcp/tools/job.py:45:PRIVESC
Security findings 3
Destructive action
highContextual riskmedium confidencegcode_save_macro builds the output path from the unsanitized agent-supplied name, so path traversal (../) writes agent-controlled content to a .nc file outside the macros directory.
macro_path = MACROS_DIR / f"{name}.nc"vector:code
Counter-argument considered
The agent-supplied name goes straight into the output path with no sanitization, so ../ or an absolute path writes a .nc file outside MACROS_DIR. Impact is limited by the .nc suffix, but nothing in the code mitigates it.
Privilege escalation
mediumContextual riskmedium confidenceThe declared safety claim that the agent cannot self-confirm movement is contradicted: the confirmation token is returned to the agent in the preview output, any live token is accepted for any action since it is not bound to a specific action, and the agent can immediately replay it, so the human-in-the-loop gate can be bypassed for machine motion.
Claude CANNOT self-confirm movement - the token enforces this at the server level.
vector:code
Counter-argument considered
The server hands the token to the agent in the preview output and asks the agent to replay it. The server cannot tell the user's confirmation from the agent's own replay, so the claim that Claude cannot self-confirm 'at the server level' does not hold.
Privilege escalation
mediumContextual riskmedium confidenceThe confirmation token is returned to the agent in the preview and consume_token's returned description is ignored, so any valid token authorizes any action and the agent can self-confirm, contradicting the 'Claude CANNOT self-confirm' guarantee for machine-moving operations.
desc = consume_token(confirmation_token)
vector:code
Counter-argument considered
The returned description is discarded, so any live token authorizes the run. The preview also hands the token to the agent, which contradicts the 'Claude cannot self-confirm' docstring.
Refuted findings 1
Candidates the review stage examined and rejected, kept for transparency.
Data exfiltration
highRefutedlow confidenceugs_run_file passes an agent-supplied arbitrary file path to send_file, which opens and uploads any readable local file to the UGS_HOST-configured endpoint (localhost by default, env-configurable), with no G-code or extension validation.
with open(file_path, "rb") as f:
Why it was refuted
Streaming a file to UGS is the tool's declared core capability. The upload goes to the configured UGS pendant (the wrapped service), not to an attacker endpoint, so there is no exfiltration sink.
Coverage gaps 1
Parts of the artifact the static analysis could not fully examine.
no_tools_extracted MCP server target with no statically extractable tools/prompts/resources
pyproject.toml