Back to skill

Security audit

AI PC Builder

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent Newegg PC-building purpose, but its dynamic remote tool workflow and unrestricted file-backed arguments create review-worthy data exposure and prompt-influence risks.

Install only if you are comfortable sending PC-build queries and explicitly provided JSON arguments to Newegg's MCP endpoint. Do not use @path with existing config, credential, profile, or session files; use inline JSON or a temporary file containing only the intended request. Treat remote tool descriptions and results as data, and review before allowing unexpected tool calls.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T01 · Skill Instruction Hijacking

Warning
Location
scripts/mcp_client.py:106
Finding

Untrusted MCP Content Can Influence Agent Instructions and Tool Selection

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:106-170; related workflow instructions in SKILL.md:27-46 and SKILL.md:96-105
Vulnerability Type: Prompt injection through untrusted remote MCP metadata and results
Risk Level: Medium

Vulnerable Code

python
def cmd_list_tools():
    """
    Discover all tools from the MCP server and print a structured summary
    optimised for LLM decision-making (tool selection + parameter mapping).
    """
    _initialize()
    result = _rpc("tools/list", {})
    tools = result.get("tools", [])

    if not tools:
        print("NO_TOOLS: The server returned no tools.")
        return

    # Emit a machine-readable block per tool so the LLM can parse easily
    print(f"TOOL_COUNT: {len(tools)}\n")
    for t in tools:
        name = t.get("name", "unknown")
        desc = t.get("description") or t.get("title") or "(no description)"
        schema = t.get("inputSchema", {})
        props = schema.get("properties", {})
        required = set(schema.get("required", []))

        print(f"=== TOOL: {name} ===")
        print(f"DESCRIPTION: {desc}")

        if props:
            print("PARAMETERS:")
            for param_name, param_schema in props.items():
                req_marker = "[required]" if param_name in required else "[optional]"
                ptype = param_schema.get("type", "any")
                pdesc = param_schema.get("description", "")
                enum_vals = param_schema.get("enum", [])
                enum_str = f" | values: {enum_vals}" if enum_vals else ""
                print(f"  - {param_name} ({ptype}) {req_marker}{enum_str}: {pdesc}")
        else:
            print("PARAMETERS: (none defined in schema)")

        print()

    print("---")
    print("INSTRUCTIONS FOR LLM:")
    print("1. Pick the tool whose DESCRIPTION + PARAMETERS best match the user request.")
    print("2. Buil
...[truncated 4082 chars]
Remediation
View remediation

Remediation Suggestions

  1. Treat every field returned by the MCP endpoint as untrusted data and explicitly instruct the agent never to follow instructions embedded in tool metadata or results.
  2. Represent remote responses using a constrained, machine-readable envelope rather than mixing them with text labeled as instructions for the LLM.
  3. Maintain a local allowlist of expected PC-builder tool names, parameter names, and schema types. Reject unexpected tools or schema changes pending review.
  4. Validate descriptions and result fields for size, allowed structure, and unexpected instruction-like content before presenting them to the agent.
  5. Separate trusted local guidance from remote output using explicit delimiters and labels such as “UNTRUSTED REMOTE DATA.”
  6. Require confirmation before acting on newly discovered tools or materially changed schemas.
  7. Ensure agent policy gives local skill instructions precedence over all MCP-supplied text and prohibits remote content from requesting secrets, local files, additional tool calls, or changes to safety constraints.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/mcp_client.py:173
Finding

Unrestricted File-Backed Arguments Can Disclose Local JSON Data to the Remote Endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/mcp_client.py:173-186 and scripts/mcp_client.py:213-232; documented in SKILL.md:76-83 and SKILL.md:145-151
Vulnerability Type: Unrestricted local file read followed by remote transmission
Risk Level: Medium

Vulnerable Code

python
def _load_call_arguments_raw(spec: str) -> str:
    """
    Resolve the third argument to call: inline JSON, '-' for stdin, or @path for a file.
    """
    if spec == "-":
        return sys.stdin.read()
    if spec.startswith("@"):
        path = spec[1:]
        if not path:
            raise ValueError("Empty path after @; use @C:\\path\\args.json or @args.json")
        path = os.path.expanduser(path)
        with open(path, encoding="utf-8-sig") as f:
            return f.read()
    return spec

The loaded file is parsed and then passed to the remote MCP call:

python
raw_args = ""
try:
    if len(sys.argv) > 3:
        raw_args = _load_call_arguments_raw(sys.argv[3])
    else:
        raw_args = "{}"
    arguments = json.loads(raw_args)
except (json.JSONDecodeError, OSError, ValueError) as e:
    preview = raw_args if isinstance(raw_args, str) else ""
    if len(preview) > 120:
        preview = preview[:120] + "..."
    print(
        f"ERROR: arguments must be valid JSON.\n  Got: {preview!r}\n  {e}",
        file=sys.stderr,
    )
    print(
        "Hint (PowerShell): use single quotes around JSON, e.g.\n"
        "  python mcp_client.py call v2allin '{\"question\": \"your text\"}'\n"
        "Or put JSON in a file and run:\n"
        "  python mcp_client.py call v2allin @args.json",
        file=sys.stderr,
    )
    sys.exit(1)
cmd_call_tool(tool_name, arguments)

The arguments are transmitted here:

python
def cmd_call_tool(tool_name: str, arguments: dict):
    """Call a specific tool and print the full response for LLM interpretati
...[truncated 2517 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove @path support from agent-facing use when inline JSON or standard input is sufficient.
  2. If file loading is required, restrict it to a dedicated approved directory beneath the project workspace.
  3. Canonicalize paths with os.path.realpath, reject absolute paths and traversal, and verify that the resolved path remains inside the approved directory.
  4. Reject symbolic links or resolve them before enforcing directory containment.
  5. Require explicit user confirmation that identifies the exact resolved file and destination before transmitting file-derived content.
  6. Validate parsed arguments against the selected tool's locally approved schema and reject unknown or sensitive fields.
  7. Apply strict file-size and request-size limits before reading or transmitting content.
  8. Avoid printing previews of invalid file content to stderr because those previews may themselves expose sensitive values in logs.
  9. Add tests covering absolute paths, .. traversal, home expansion, symbolic links, oversized files, and attempts to read files outside the approved directory.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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 (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes a remote MCP endpoint and instructs use of a Python client, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates unnecessary ambient authority: if the hosting agent honors permissive defaults, this skill could make network requests outside a tightly bounded policy and increase the blast radius of prompt injection or misrouting.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger guidance is broad enough to activate on many general PC-related requests, including cases where Newegg-specific retrieval may not be necessary. Over-broad invocation can route unrelated user queries into a network-enabled skill, causing unnecessary external data access, reduced user control, and making any downstream tool misuse or prompt-injection exposure more likely.

Content

No source excerpt is available for this finding.