Back to skill

Security audit

Shopprentice

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Fusion 360 furniture-modeling tool, but it installs and exposes powerful local execution paths that need review before use.

Install only if you are comfortable with a local Fusion 360 add-in that can execute generated Python and modify CAD documents. Prefer cloning or downloading a pinned release and inspecting the installer instead of using curl | bash. Run it only in a trusted local environment, keep valuable Fusion documents backed up, and avoid bypassing agent sandbox protections unless you understand the full local-system access being granted.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:26
Finding
Unpinned Remote Installer Is Piped Directly to Bash<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:26-27` **Additional Locations**: `README.md:32`, `DEVELOPMENT.md:11-23`, `install-openclaw.sh:6`, `install.sh:6-7`, `dev/package-clawhub.sh:65-66` **Vulnerability Type**: Remote payload retrieval and immediate shell execution **Risk Level**: High ### Vulnerable Code ```yaml installMethod: - description: "One-line installer clones the GitHub repo and symlinks the Fusion 360 add-in. Source is fully auditable at https://github.com/ShopPrentice/shopprentice/blob/main/install.sh" command: "curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install.sh | bash" ``` Equivalent installation instructions are repeated in several project files: ```bash curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install.sh | bash ``` ### Technical Analysis The documented installation method downloads a shell script from the mutable `main` branch and sends its contents directly to Bash. It does not pin a release tag or commit, validate a cryptographic checksum, verify a signature, or give the user an opportunity to inspect the retrieved script before execution. Consequently, the payload reviewed in this audit is not necessarily the payload that a future user will execute. The current checked-in installer appears related to the declared installation workflow, but that does not eliminate the delivery-channel risk. The installer runs with the invoking user's privileges and makes persistent changes under the user's home directory and application configuration, including: - Cloning code into `~/.shopprentice/repo` - Installing agent instructions under `~/.claude` or `~/.codex` - Symlinking the Fusion 360 add-in - Registering a localhost MCP server in supported clients These operations make integrity verification especially important. ### Attack Path 1. An attacker compromises the ShopPrentice GitHub account, repository, release process, or another mechanism c ...[truncated 1071 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all `curl | bash` installation instructions. 2. Publish versioned release artifacts and pin installation instructions to an immutable release or commit. 3. Publish SHA-256 or stronger checksums through a separately protected release channel. 4. Sign release artifacts, and require signature verification before execution. 5. Use a download-review-execute workflow, for example: ```bash curl -fL -o install.sh \ https://raw.githubusercontent.com/ShopPrentice/shopprentice/<immutable-commit>/install.sh echo "<expected-sha256> install.sh" | shasum -a 256 -c - less install.sh bash install.sh ``` 6. Ensure the installer exits on download and verification failures. Prefer `curl --fail --show-error --location`. 7. Document the exact files and configuration entries modified by installation. 8. Keep the default installation narrowly scoped, and require explicit flags for persistent agent configuration and MCP registration. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
addin/server/mcp_server.py:509
Finding
Unauthenticated Local MCP Endpoint Exposes Arbitrary Python Execution<![CDATA[ ## Vulnerability Details **File Location**: `addin/server/mcp_server.py:509-569` **Related Locations**: `addin/ShopPrentice.py:33-34,75-80`; `addin/server/mcp_server.py:67-109,137-169,583-606`; `addin/tools/execute_script.py:281-307,383-434,557-580` **Vulnerability Type**: Unauthenticated code-execution API **Risk Level**: Critical ### Vulnerable Code The add-in starts the service on a fixed localhost port: ```python HOST = 'localhost' PORT = 9100 mcp, server, thread = start_mcp_server( host=HOST, port=PORT, tools=registered_tools, resources=registered_resources ) ``` Incoming requests are parsed and dispatched without authentication or authorization: ```python def do_POST(self): """Handle MCP protocol requests""" try: content_length = int(self.headers.get('Content-Length', 0)) post_data = self.rfile.read(content_length) request_data = json.loads(post_data.decode('utf-8')) session_id = self.headers.get('Mcp-Session-Id') method = request_data.get("method", "?") if app: app.log(f"[session] {method} | header={session_id or '(none)'}") response, response_session_id = asyncio.run( self.mcp_server.handle_request(request_data, session_id=session_id) ) self._send_json_response(response, session_id=response_session_id) except json.JSONDecodeError: self.send_error(400, "Invalid JSON") except Exception as e: self.send_error(500, str(e)) ``` Tool calls are passed to registered handlers: ```python elif method == "tools/call": resp = await self._handle_tools_call( request_id, params, session_id=session_id ) return resp, session_id ``` ```python tool_name = params.get("name") arguments = params.get("arguments", {}) if tool_name not in self.tools: return self._create_error_response( request_id, -32601, f"Tool not found: {tool_name}" ) tool_item = self.tools[tool_name] if t ...[truncated 4145 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random authentication token during installation or add-in startup. 2. Store that token with user-only filesystem permissions and require it on every MCP request. 3. Use an authorization header rather than treating `Mcp-Session-Id` as proof of identity. 4. Reject unauthenticated requests before JSON-RPC dispatch. 5. Prefer authenticated local IPC with operating-system peer credential checks over a fixed TCP port where supported. 6. Remove `Access-Control-Allow-Origin: *`. If browser access is required, use an explicit allowlist and implement strict origin validation. 7. Validate the `Host` header and reject unexpected hosts to reduce DNS-rebinding exposure. 8. Add per-tool authorization, with a separate high-risk permission for `execute_script`, destructive operations, and file exports. 9. Require explicit in-application user approval before enabling arbitrary script execution for a new client. 10. Replace the document-only sandbox with a real least-privilege OS sandbox for untrusted generated code. 11. Restrict filesystem and network capabilities where technically possible. 12. Log authenticated client identity, tool name, target document, and approval state. 13. Rotate credentials on reinstall, suspected compromise, and user request. 14. Add rate limits and request-size limits to reduce local denial-of-service risk. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
addin/tools/execute_script.py:365
Finding
Remote force_clean Argument Bypasses Destructive Document Safety Checks<![CDATA[ ## Vulnerability Details **File Location**: `addin/tools/execute_script.py:365-380` **Related Locations**: `addin/tools/execute_script.py:235-278,559-580`; `addin/palette/param_editor.py:111-132` **Vulnerability Type**: Caller-controlled bypass of destructive-operation safeguards **Risk Level**: High ### Vulnerable Code The handler accepts `force_clean` directly from the MCP caller: ```python def handler(script: str, sandbox: bool = False, clean: bool = False, script_path: str = None, force_clean: bool = False) -> dict: """Execute a Fusion API Python script.""" ``` The normal provenance and unsynchronized-change check is skipped whenever the caller supplies `force_clean=True`: ```python # Guard: clean=True destroys the timeline + user parameters. Only allow # it on documents the add-in knows were built by a tracked script AND # have no unsynced UI changes. force_clean=True bypasses the check for # the rare "I really do want to wipe this doc" case. if clean and not force_clean: guard_result = _check_clean_safe(script) if guard_result is not None: return guard_result ``` When cleaning proceeds, the active design is destructively modified: ```python def _clean_design(): """Delete all timeline features and user parameters from the active design.""" import adsk.fusion design = adsk.fusion.Design.cast(app.activeProduct) if not design: return tl = design.timeline for i in range(tl.count - 1, -1, -1): try: item = tl.item(i) entity = item.entity if entity and hasattr(entity, 'deleteMe'): entity.deleteMe() except Exception: pass root = design.rootComponent for i in range(root.occurrences.count - 1, -1, -1): try: root.occurrences.item(i).deleteMe() except Exception: pass params = design.userParameters for i in range(params.count - 1, -1, -1): tr ...[truncated 2708 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `force_clean` from the remotely callable MCP schema. 2. Require an explicit confirmation inside Fusion 360 before destructive cleaning. 3. Bind confirmation to: - The authenticated client - The exact document identifier - A hash of the proposed operation - A short expiration time 4. Return a one-time confirmation token from the Fusion UI and require that token for the destructive request. 5. Never permit an agent instruction or boolean request field alone to represent user consent. 6. Create an automatic backup or saved copy before deleting existing model content. 7. Refuse destructive cleaning when the document has unsaved or unsynchronized changes unless the user confirms those exact conditions. 8. Display the document name and a summary of affected features and parameters in the confirmation dialog. 9. Preserve a durable audit record of the approving user action and subsequent destructive request. 10. Keep the safe additive workflow as the default and require a separate authenticated privilege for clean rebuilds. ]]>
Vulnerability Patterns
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (284)

Chaining Abuse

High
Category
Tool Misuse
Content
curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install.sh | bash -s -- --all

# no flags = auto-detect installed clients + MCP
curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install.sh | bash
```

### OpenClaw install
Confidence
97% confidence
Finding
The explicit shell pipeline `| bash` is the dangerous element that converts downloaded network content directly into executable commands with no validation boundary. In a developer-facing skill, this is especially risky because users may run it in privileged, tool-rich environments where compromise enables persistence, credential theft, or supply-chain tampering.

Chaining Abuse

High
Category
Tool Misuse
Content
For [OpenClaw](https://openclaw.ai) users there's a dedicated installer:

```bash
curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install-openclaw.sh | bash
```

### Local clone install
Confidence
97% confidence
Finding
This OpenClaw example uses the same chaining pattern, turning a remote HTTP response into immediate shell execution. The convenience-focused presentation without warnings normalizes unsafe installation behavior and increases the chance users will execute untrusted code blindly.

Chaining Abuse

High
Category
Tool Misuse
Content
One command — no clone needed:

```bash
curl -sSL https://raw.githubusercontent.com/ShopPrentice/shopprentice/main/install.sh | bash
```

This installs the woodworking skill for supported clients it detects, including Claude Code and Codex, and optionally sets up the MCP server for live Fusion 360 execution. For installer flags, OpenClaw users, and local clone installs, see [DEVELOPMENT.md](DEVELOPMENT.md#install-options).
Confidence
97% confidence
Finding
The `curl ... | bash` pattern is especially dangerous because it chains retrieval and execution into one step, removing the opportunity for human review and making accidental or malicious remote changes immediately executable. In the context of a skill that also installs client integrations and optionally an MCP server, this could result in broad local-system changes from a single pasted command.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description emphasizes AI-driven furniture CAD generation from user inputs like text, images, or links. This code chunk does not implement or directly invoke any modeling, AI inference, furniture generation, joinery creation, image/link ingestion, or production-ready CAD synthesis. Instead, it initializes infrastructure: module hot-reloading, a localhost MCP server, task/action/session managers, and a parameter editor UI. The file’s own docstring further describes tool-style capabilities such as design introspection, timeline capture, script execution, and screenshots, which are materially different from the declared primary purpose. While this may be part of a larger system, the supplied code chunk’s actual behavior is centered on exposing remote tooling and management services, so the description does not accurately represent this code.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description emphasizes AI-driven furniture model generation from prompts, images, or links. This code chunk does not implement model generation, AI interpretation, image/link ingestion, or furniture/joinery creation. Instead, it provides a dockable HTML parameter editor for existing Fusion 360 user parameters, updates parameter expressions, patches those values into a tracked script, optionally saves the script file, and triggers sync/rebuild tasks. These are materially different capabilities from the declared primary purpose, so this chunk is a description/behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The supplied code chunk is package initialization code for a primitives/registry layer. It exposes classes like Tool, Resource, Prompt, Item, and registry accessors, which indicates infrastructure for schema registration rather than functionality for parametric furniture modeling. There is nothing in this chunk suggesting CAD generation, Fusion 360 operations, geometry creation, joinery logic, or multimodal AI input handling. Because the actual code's primary purpose is materially different from the declared description, this is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The supplied code chunk is a generic metadata/annotation schema helper. Its functions are limited to storing audience, priority, and last-modified fields and converting them to dictionary/JSON form. This is materially unrelated to the declared purpose of parametric furniture modeling in Fusion 360. The primary behavior shown does not implement or support the advertised CAD-generation capabilities in any evident way, so this is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a domain-specific AI skill for generating production-ready furniture CAD models in Fusion 360 from various inputs. The supplied code does not implement any of those capabilities. Instead, it is a small infrastructure utility that wraps MCP primitives with handlers, provides type identification, serialization delegation, and a method to call the handler. There is no evidence of Fusion 360 integration, CAD generation, geometry creation, furniture logic, joinery logic, or multimodal input handling. This is a material purpose mismatch rather than a mere supporting detail.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The supplied code chunk is a small utility class for representing and serializing prompt definitions. It manages prompt metadata and arguments and converts them to dictionaries or JSON. There is nothing in this code related to Fusion 360, CAD geometry, furniture modeling, joinery, image/reference-link handling, or AI generation. This is a materially different primary purpose from the declared description, so it is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The supplied code chunk is a generic registry utility. It stores, retrieves, lists, counts, and clears items by type (tool/resource/prompt) and exposes a singleton instance with convenience wrappers. There is nothing in this code related to furniture design, CAD model generation, joinery, Fusion 360 APIs, or AI-powered interpretation of user inputs such as natural language, images, or reference links. This is a materially different primary purpose from the declared description, so it should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The supplied code chunk is a standalone utility class for representing resource metadata and converting it to dictionaries/JSON. It does not contain any functionality related to Fusion 360, parametric furniture modeling, CAD generation, joinery creation, or multimodal AI input handling. This is a materially different primary purpose from the declared description, so it is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The supplied code chunk does not implement furniture design, CAD generation, Fusion 360 integration, AI inference, or processing of user prompts/images/links. Instead, it is a generic utility class for describing tools and their JSON schemas in an MCP-style framework. This is a materially different primary purpose from the declared description, so the description does not accurately represent the code's actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description is about AI-driven furniture CAD generation from prompts, images, or links. This code chunk does not perform model generation, natural-language/image/reference-link processing, or joinery creation. Instead, its primary purpose is to observe Fusion 360 UI command termination events, detect design changes, maintain baselines/cursors, and persist action logs to local files. These are materially different capabilities and include undeclared logging/persistence behavior. While such logging could support a larger CAD-generation skill, this specific chunk’s behavior is not accurately represented by the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This code chunk does not perform AI-powered furniture modeling, natural-language/image/reference-link interpretation, or CAD model generation. Its primary purpose is document/script provenance tracking and sync-state persistence for Fusion 360 sessions. While such tracking could be a supporting subsystem within a larger modeling add-in, the declared description for the skill presents the skill itself as a model-generation capability, which this code chunk does not implement. Additionally, the code writes and reads a sidecar JSON file in the user's home directory, an undeclared resource access not reflected in the declared permissions. Therefore the description does not accurately represent this code chunk's actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description is about AI-driven furniture/CAD generation functionality. This code chunk does not implement modeling, natural-language/image/link interpretation, joinery generation, or CAD creation logic. Instead, it provides infrastructure: an MCP-compatible HTTP server, request routing, session management, tool/resource registration and invocation, main-thread execution handling, queueing, and health endpoints. While this could support the overall product, the actual behavior of this chunk is materially different from the declared primary purpose and includes undeclared network-serving/API exposure capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code chunk does not perform AI-powered furniture modeling or CAD generation from natural language, images, or links. Its primary purpose is backend session coordination for a Fusion 360 add-in: tracking MCP sessions, activating the right document, serializing execution, handling ownership conflicts, and preserving per-document state. These are infrastructural capabilities not reflected in the declared description. While such functionality could support a larger furniture-modeling system, this specific code chunk’s behavior is materially different from the declared skill purpose, so this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents an AI-driven furniture/CAD generation skill, but this code chunk does not perform any furniture modeling, CAD generation, natural-language/image/reference-link processing, or joinery creation. Instead, it provides internal event/task orchestration infrastructure for Fusion 360: starting/stopping a custom event handler, posting tasks, and invoking callbacks on the main thread. This is a materially different primary purpose from the declared functionality, so the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The declared description focuses on AI-driven parametric furniture model generation in Fusion 360. The supplied code does not show that behavior; instead it registers a wide operational toolkit with many capabilities beyond furniture modeling, including executing scripts, syncing/exporting scripts, managing and claiming documents, generating screenshots/product shots/videos, checking queue and document status, and reloading the add-in. Some imported tools could support CAD modeling workflows, but the visible primary behavior here is broad tool registration rather than specifically generating production-ready furniture CAD from natural language, images, or links. This indicates a material description-to-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The supplied code does not implement AI-driven furniture generation, natural-language/image/reference-link processing, or production-ready joinery creation. Instead, it serves as a shared helper export layer for design introspection and structured extraction of existing Fusion 360 model data. While such capture utilities could be supporting infrastructure for a CAD tool, the declared purpose specifically emphasizes generative modeling capabilities, whereas this chunk is about analyzing/capturing model features. That is a materially different behavior for this code chunk, so this is a description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises an AI-powered furniture modeling tool that creates production-ready CAD models from natural language, images, or links. The provided code does not implement any of those user-facing generation capabilities. Instead, it is a low-level Fusion 360 utility focused specifically on analyzing and capturing properties of existing extrude features, including sketch lookup, profile matching, body-name inference, and participant-body detection via timeline/volume comparisons. While this could be a supporting internal component of a larger CAD system, the code chunk itself materially differs from the declared purpose and exposes an undeclared capability: feature inspection/capture rather than generative furniture modeling.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description emphasizes AI-powered generation of parametric furniture CAD models from user inputs such as natural language, images, or links. The supplied code does not implement any AI, input parsing, furniture-specific modeling, joinery generation, or model creation. Instead, it reads and captures details from existing Fusion 360 features, including mirror planes, move transforms, chamfer/fillet edges, sweep profiles and paths, split-body tools, and removed body names. This is a materially different primary purpose: feature introspection/serialization rather than furniture-model generation. No suspicious extra permissions or triggers are visible in this chunk, but the behavior still does not accurately match the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The supplied code does not implement an AI-powered furniture modeling skill. It is a low-level Fusion 360 utility for reading and inferring properties of rectangular pattern features in an existing design. It extracts direction vectors from CAD entities, rolls the timeline to inspect feature state, gathers bodies and inputs, and detects pattern copies from component bodies. These behaviors are related to CAD internals, but they are materially different from the declared primary purpose of generating furniture models from user prompts, images, or links. There is no evidence here of AI inference, prompt handling, image/link ingestion, furniture-specific logic, or joinery generation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a high-level AI furniture modeling capability that generates production-ready CAD from natural language, images, or reference links. The supplied code does not implement any of that behavior. Instead, it introspects existing Fusion 360 objects and returns structured information about sketch planes and construction plane definitions. While such helpers could support a larger CAD add-in, this chunk’s actual purpose is metadata capture/serialization for planes, not AI-powered furniture modeling or model generation. This is a material description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises an AI-powered parametric furniture modeling skill that generates CAD models from natural language, images, or reference links. The supplied code chunk does none of that. Instead, it is a low-level helper for reading and exporting information from an existing Fusion 360 sketch. It captures sketch plane/orientation, curves (lines, arcs, circles, splines), profiles, dimensions, and geometric constraints, and resolves references to projected geometry/BRep entities. This behavior is related to CAD/sketch processing generally, but its primary purpose is analysis/serialization of sketch content for capture or reconstruction, not AI-driven furniture generation or joinery creation. No triggers or permissions are implicated, but the core behavior materially differs from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The declared description presents an end-user AI furniture modeling skill that can create production-ready CAD models from natural language, images, or links. The supplied code chunk instead implements a backend generator that walks already-structured capture_design output and emits Fusion 360 Python scripts. It also provides helpers for variant counting, ambiguity inspection, prefix-only scripts, and single-feature script generation. These behaviors are related to CAD automation in Fusion 360, but they do not match the declared primary capability of AI-driven furniture modeling from unstructured inputs, nor do they show furniture- or joinery-specific functionality. Therefore the description materially overstates and misrepresents what this code chunk actually does.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_deps_anchoring.py:27

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_document_tracker.py:30

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_session_manager.py:28