Back to skill

Security audit

FreeCAD MCP

Security checks for vulnerabilities and agentic risk

Overview

This FreeCAD integration is mostly coherent, but it exposes powerful unauthenticated local control, including arbitrary Python execution, without enough safeguards or warning.

Install only if you are comfortable giving connected local agents broad control over FreeCAD and effectively the FreeCAD Python environment. Use it only with trusted prompts and clients, avoid exposing the RPC port beyond localhost, consider running it in an isolated user account or VM for sensitive CAD work, and treat execute_code as equivalent to running local Python on your machine.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
addon/FreeCADMCP/rpc_server/rpc_server.py:168
Finding

Unauthenticated Arbitrary Python Code Execution in the FreeCAD Process

Content
View full analysis
dict[str, Any]: output_buffer = io.StringIO() def task(): try: with contextlib.redirect_stdout(output_buffer): exec(code, globals()) FreeCAD.Console.PrintMessage("Python code executed successfully.\n") return True except Exception as e: FreeCAD.Console.PrintError( f"Error executing Python code: {e}\n" ) return f"Error executing Python code: {e}\n" ``` The RPC service registers the method without authentication or authorization: ```python rpc_server_instance = SimpleXMLRPCServer( (host, port), allow_none=True, logRequests=False ) rpc_server_instance.register_instance(FreeCADRPC()) def server_loop(): FreeCAD.Console.PrintMessage(f"RPC Server started at {host}:{port}\n") rpc_server_instance.serve_forever() ``` The same capability is exposed directly as an MCP tool: ```python @mcp.tool() def execute_code(ctx: Context, code: str) -> list[TextContent | ImageContent]: """Execute arbitrary Python code in FreeCAD. ``` ### Technical Analysis Caller-controlled input reaches Python's `exec()` with the FreeCAD process globals. There is no authentication, authorization, source validation, user confirmation, restricted built-in environment, process isolation, or allowlist of permitted operations. Although the XML-RPC service binds to `localhost` by default, any local process able to connect to port `9875` can invoke the method. The MCP layer also exposes the same primitive to any client with access to the MCP server. An attacker who compromises or influences an MCP client, includ ...[truncated 1994 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
addon/FreeCADMCP/rpc_server/parts_library.py:8
Finding

Parts-Library Path Traversal Permits Access Outside the Intended Directory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:19
Finding

Installation Instructions Use an Unversioned Mutable Registry Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (25)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The server exposes arbitrary Python execution as a normal RPC feature even though the surrounding service is for CAD automation, making the capability far broader than necessary. In skill context this is more dangerous because the RPC server is intended to accept remote requests and therefore turns FreeCAD into a code-execution endpoint for any reachable client.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

Remote callers can execute Python code with no warning, confirmation, or authorization check, so a user starting the RPC server may unknowingly expose full control of their FreeCAD session and host environment. The lack of friction or visibility makes exploitation easier and reduces the chance the user notices malicious actions.

Content

No source excerpt is available for this finding.

exec() call detected

High
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The RPC method execute_code passes untrusted remote input directly into exec(code, globals()), which gives a caller arbitrary Python execution inside the FreeCAD process. That enables full compromise of the user context running FreeCAD, including filesystem access, process execution, data theft, and persistence, and it is especially dangerous because the server also exposes GUI/application globals.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/rpc_server.py (reported line 177)May include surrounding context.

python
def task():
            try:
                with contextlib.redirect_stdout(output_buffer):
                    exec(code, globals())
                FreeCAD.Console.PrintMessage("Python code executed successfully.\n")
                return True
            except Exception as e:

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The server is presented as a FreeCAD integration tool, but it exposes a general-purpose code execution path via the underlying connection object. In this context, that materially expands the trust boundary: any caller able to use the MCP tool can run arbitrary Python inside the FreeCAD process, potentially accessing the filesystem, network, and local environment rather than just CAD operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The execute_code tool directly accepts attacker-controlled Python and forwards it to the FreeCAD backend for execution without validation, sandboxing, or capability restriction. This is effectively remote code execution in the local FreeCAD context and could be used to read or modify files, execute system commands, exfiltrate data, or pivot into other local resources available to the process.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The arbitrary code execution tool is exposed with a neutral docstring and no explicit warning that it can run dangerous Python in the FreeCAD environment. In an MCP/agent setting, absence of a strong warning and confirmation makes accidental invocation more likely and obscures the severity of the action from users and higher-level orchestration systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README explicitly advertises high-risk capabilities including execute_code for arbitrary Python execution and object deletion, but it does not provide a prominent warning, trust boundary explanation, or safe-use guidance. In an MCP context, exposing these tools to an LLM-driven client increases the chance of unsafe prompting, unintended destructive actions, or execution of unreviewed code within the FreeCAD environment.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 3)May include surrounding context.

md
# FreeCAD MCP Skill

Enable AI agents to control FreeCAD via the Model Context Protocol (MCP). Create 3D models programmatically, generate parts from descriptions, and automate CAD workflows.

## Features

Rp1

Medium
Category
MCP Rug Pull
Confidence
85% confidence
Finding

The installation instruction uses npx clawhub install openclaw-freecad-mcp without pinning a specific version or integrity mechanism. That exposes users to supply-chain risk because the package resolved at install time could change, be typosquatted, or be replaced with a malicious release, and this skill is especially sensitive because it enables local RPC control of FreeCAD.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The RPC API allows remote deletion of document objects immediately and silently, which can destroy work or sabotage analyses if an untrusted client can connect. In this CAD/engineering context, integrity of models matters, so destructive operations over unauthenticated RPC are more concerning than a normal local scripting interface.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This endpoint captures the active GUI view, writes it to disk temporarily, and returns the image over RPC without any user awareness or access control. That can leak sensitive design information from the current workspace to any client able to reach the server, and temporary-file use adds minor residual exposure if cleanup fails.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

serialize_object recursively exports document metadata, object metadata, placement, shape statistics, view state, and every property in PropertiesList, with no filtering or sensitivity controls. In an RPC server context, this can expose file paths, internal model data, embedded metadata, or plugin-defined properties to remote callers, creating an information disclosure surface that is broader than necessary.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code sends user input to the external Groq-hosted LLM service and depends on an API key, but it provides no disclosure, consent flow, or data-handling controls. If users provide proprietary CAD designs, credentials, or sensitive project details, that data may be transmitted off-host to a third-party service without adequate justification or safeguards.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill launches a local MCP server process and automatically loads all tools exposed by that server into a ReAct agent, giving the model broad action capabilities with no visible allowlist, scoping, or user-approval gate. In this context, the stated purpose is only a generic CAD assistant, so unrestricted tool loading can let prompt-influenced model behavior invoke powerful local operations beyond what is necessary.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The delete_object tool performs destructive actions immediately with no confirmation, dry-run mode, or recovery guidance. In an agent-driven workflow, ambiguous instructions or prompt injection can lead to unintended deletion of CAD objects, causing data loss or disruption even if the scope is limited to the active FreeCAD document.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The prompt instructs the agent to use execute_code for 'detailed customization or specialized operations' and treats arbitrary scripting as a normal fallback path. This increases the likelihood that an LLM will invoke dangerous code execution for routine tasks, turning a powerful but exceptional capability into a default behavior and raising the probability of accidental misuse or prompt-driven abuse.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/rpc_server.py (reported line 77)May include surrounding context.

python
)
                    setattr(obj, prop, placement)

                elif isinstance(getattr(obj, prop), FreeCAD.Vector) and isinstance(
                    val, dict
                ):
                    vector = FreeCAD.Vector(

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

getattr(doc, obj.analysis).addObject(...) lets a remote caller choose an attribute on the document object and then invoke addObject on it without validating that it is an intended analysis container. In FreeCAD this can let an attacker manipulate unintended document structures or trigger methods on the wrong object graph, increasing attack surface and risking document corruption or misuse of internal APIs.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/rpc_server.py (reported line 287)May include surrounding context.

python
try:
                if obj.type == "Fem::FemMeshGmsh" and obj.analysis:
                    from femmesh.gmshtools import GmshTools
                    res = getattr(doc, obj.analysis).addObject(ObjectsFem.makeMeshGmsh(doc, obj.name))[0]
                    if "Part" in obj.properties:
                        target_obj = doc.getObject(obj.properties["Part"])
                        if target_obj:

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/rpc_server.py (reported line 315)May include surrounding context.

python
}
                    obj_type_short = obj.type.split("::")[1]
                    method_name = "make" + obj_type_short
                    make_method = fem_make_methods.get(obj_type_short, getattr(ObjectsFem, method_name, None))

                    if callable(make_method):
                        res = make_method(doc, obj.name)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

This line again allows remote input to select an arbitrary document attribute and then calls addObject on the result, with no verification that the target is the intended analysis object type. Even if not full RCE, it creates a confused-deputy condition where an RPC caller can attach objects into unexpected places or cause application instability and document tampering.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/rpc_server.py (reported line 326)May include surrounding context.

python
else:
                        raise ValueError(f"No creation method '{method_name}' found in ObjectsFem.")
                    if obj.type != "Fem::AnalysisPython" and obj.analysis:
                        getattr(doc, obj.analysis).addObject(res)
                else:
                    res = doc.addObject(obj.type, obj.name)
                    set_object_property(doc, res, obj.properties)

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · addon/FreeCADMCP/rpc_server/serialize.py (reported line 73)May include surrounding context.

python
for prop in obj.PropertiesList:
            try:
                result["Properties"][prop] = serialize_value(getattr(obj, prop))
            except Exception as e:
                result["Properties"][prop] = f"<error: {str(e)}>"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The agent is configured to launch an external MCP server via stdio using the uv command, which is a subprocess execution path. This file contains no confirmation prompt, user-facing log, or explanatory warning about that behavior, so users would not be informed that local code/tooling will be executed.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The metadata description at L04 says "Add your description here," which is not an actual description of the skill and therefore misrepresents the package's documented intent. Because no real manifest purpose is provided, the documentation fails to state what the skill does while the package clearly defines a distributable executable entry point at L16.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: mcp has 12 known advisory(ies) (CVE-2025-53366 (MCP Python SDK vulnerability in the FastMCP Server causes validation error, lead); CVE-2025-66416 (Model Context Protocol (MCP) Python SDK does not enable DNS rebinding protection); CVE-2026-52870 (MCP Python SDK: Experimental task handlers allow any client to access and cancel) +9 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The dependency specification uses a lower-bound range (mcp[cli]>=1.4.1) rather than pinning or constraining to a known-safe version, so installations may resolve to vulnerable releases depending on environment and index state. Given the cited advisories against the MCP Python SDK, this creates supply-chain uncertainty and can expose the skill to known issues in server validation, DNS rebinding protection, or task access control if an affected version is installed.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function is named and implemented as an object editor, calling freecad.edit_object, but the docstring states 'This tool is used when the create_object tool cannot handle the object creation.' That wording contradicts the actual behavior by describing creation fallback rather than editing behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.