Back to skill

Security audit

Shipment Tracker

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its package-tracking purpose, but its generated browser-use fallback can turn shipment-file link text into executable Python code if a user or agent runs the provided command.

Review this skill before installing. It is not clearly malicious, but only use it with shipment files you trust, avoid running the generated browser-use command for sensitive packages, and be aware that the fallback sends tracking information to third-party cloud/LLM services. The generated command should be fixed to pass URLs as data, not as interpolated Python source.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shipment_tracker.py:251
Finding

Arbitrary Python Code Injection Through Generated Browser-Use Command

Content
View full analysis

Vulnerability Details

File Location: scripts/shipment_tracker.py, lines 143–145 and 251–264
Vulnerability Type: Command generation using untrusted shipment data without escaping
Risk Level: High

The application reads a user-controlled tracking link from a Markdown shipment table and later embeds that value directly into executable Python source presented as a browser-use fallback command.

Relevant source of untrusted input at lines 143–145:

python
# Extract URL from markdown link syntax [text](url)
link_match = re.search(r"\[.*?\]\((.*?)\)", link_raw)
link = link_match.group(1) if link_match else link_raw

The untrusted link is assigned to tracking_url and interpolated into generated Python code at lines 251–264:

python
result["browser_use_command"] = f"""python3 -c "
import asyncio
from browser_use import Agent, Browser, ChatBrowserUse
async def main():
    browser = Browser(use_cloud=True)
    llm = ChatBrowserUse()
    agent = Agent(
        task='Go to {result["tracking_url"]} and extract the current tracking status, delivery date, and location',
        llm=llm, browser=browser
    )
    result = await agent.run(max_steps=10)
    print('TRACKING:', result)
asyncio.run(main())
\""""

Technical Analysis

shipment.link originates from the Link column of the supplied Markdown file and is not validated as a URL or escaped for use in Python source. During a browser-use fallback, result["tracking_url"] is inserted inside a single-quoted Python string in a python3 -c command.

An attacker-controlled link containing a single quote and a Python expression can terminate or alter the intended string expression. For example, a raw Link cell shaped like the following can cause an operating-system command to execute when the generated command is run:

text
https://example.invalid/'+__import__('os').system('id')+'

This changes the generated task ...[truncated 2233 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not generate executable Python source from shipment data. Replace the inline python3 -c output with a fixed, reviewed helper script that accepts the tracking URL as a data argument.

  2. Pass values through argument boundaries. If a command must be displayed, pass the URL through sys.argv rather than interpolating it into Python code. Generate any shell representation with shlex.quote, while treating shell quoting as defense in depth rather than the primary fix.

  3. Prefer structured output. Emit the fallback request as JSON containing separate fields such as tracking_url and task, and have trusted application code invoke the browser-use API without evaluating generated source.

  4. Validate tracking URLs before use. Parse links with urllib.parse.urlsplit and require:

    • The https scheme.
    • No embedded credentials.
    • A hostname from an explicit carrier-domain allowlist.
    • Rejection of control characters, quotes, and malformed URLs.
  5. Do not trust a supplied link when a carrier is known. Generate the URL from the carrier's fixed template and a strictly validated tracking number instead of honoring an arbitrary Link field.

  6. Add regression tests. Include shipment links containing single quotes, double quotes, backslashes, newlines, Python expressions, shell metacharacters, and malformed Markdown. Verify that none are incorporated into executable source and that invalid or non-carrier URLs are rejected.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises capabilities that include file reads and outbound network access, and it additionally embeds a complete Python/browser-use command that would invoke shell/Python execution and send tracking data to external cloud services, yet it declares no explicit tool scope such as permissions or allowed-tools. This creates a least-privilege failure: an agent platform may over-grant access or activate the skill without clearly constraining file, network, and execution behaviors, increasing the chance of unintended data exposure or command execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation text is broad enough to trigger on ordinary mentions of shipments, package status, or delivery updates, which can cause the skill to engage in contexts the user did not intend. Because the skill reads a local shipments file and may initiate network-based tracking workflows, overbroad invocation increases privacy risk and unnecessary data handling, especially given the documented cloud browser fallback.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The docstring materially understates the real behavior: basic urllib-based checking is only implemented for USPS, while other carriers require a browser-use fallback. In this skill, misleading capability and privacy claims are dangerous because operators may assume package data is handled locally when the generated fallback command is designed to use cloud-backed browser automation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The implementation silently falls back to generating a browser-use command for all non-USPS carriers, despite presenting itself as a multi-carrier tracker. In this skill's context, that is security-relevant because the fallback explicitly uses Browser(use_cloud=True), which can send tracking numbers and shipment URLs to cloud services, creating a privacy and data-handling risk users may not expect from a local tracking utility.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.