Back to skill

Security audit

Fetch Agents

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims by contacting Fetch.ai Agentverse agents, but it also uses an API key, sends user prompts externally, and stores/reuses identity and response state in ways users should review before installing.

Install only if you are comfortable sending selected prompts to Fetch.ai Agentverse agents and using an AGENTVERSE_API_KEY for mailbox registration. Avoid submitting sensitive, private, or proprietary content; run it in a limited environment; and treat the persistent seed and /tmp response file as local state that may need cleanup or tighter permissions on shared machines.

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

Warning
Location
scripts/call.py:91
Finding

Persistent Agent Identity Seed Stored Without Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fire.sh:5
Finding

Predictable Shared Temporary File Allows Response Disclosure, Tampering, and Symlink Clobbering

Content
View full analysis
"$OUTFILE" nohup python3 "$SCRIPT_DIR/call.py" "$@" > "$OUTFILE" 2>/dev/null & ``` `scripts/result.sh:3-19`: ```bash OUTFILE="/tmp/fetch-agents-$(whoami)-response.txt" if [ ! -f "$OUTFILE" ]; then echo "No pending request. Run fire.sh first." exit 1 fi WAITED=0 while ! grep -q "RESPONSE_START" "$OUTFILE" 2>/dev/null && [ $WAITED -lt 90 ]; do sleep 5 WAITED=$((WAITED + 5)) done if ! grep -q "RESPONSE_START" "$OUTFILE" 2>/dev/null; then echo "Timeout: no response after ${WAITED}s." exit 1 fi # Extract everything after the marker sed -n '/---RESPONSE_START---/,$ p' "$OUTFILE" | tail -n +2 ``` ### Technical Analysis The scripts use a deterministic pathname under the globally shared `/tmp` directory. The output file is opened through ordinary shell redirection without exclusive creation, ownership validation, symbolic-link rejection, or an explicitly restrictive permission mode. Shell redirection follows symbolic links. Consequently, if an attacker can pre-create the predictable pathname as a symbolic link, invoking `fire.sh` can truncate and subsequently write to another file that the victim is permitted to modify. The same pathname is reused for every request made by a user. Concurrent calls can overwrite or interleave state, and `result.sh` does not correlate a result with a particular request. The response file is also not removed after retrieval. Depending on the victim's umask, remote-agent responses may remain readable to other local users. ### Attack Path **Symlink clobbering path:** 1. A local attacker predicts `/tmp/fetch-agents--response.txt`. 2. The a ...[truncated 1549 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:12
Finding

Unpinned Third-Party Agent Dependencies Create Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (10)

Tainted flow: 'req' from os.environ.get (line 139, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/call.py (reported line 47)May include surrounding context.

python
},
    )
    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            data = json.loads(resp.read())
        agents = data.get("agents", [])
        if agents:

Tainted flow: 'req' from os.environ.get (line 139, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The code reads AGENTVERSE_API_KEY from the environment and posts it to a local HTTP /connect endpoint for mailbox registration. While this appears intended functionality, it creates a credential flow not disclosed in the skill description and relies on an unauthenticated localhost service, so a compromised or unexpected local listener on that port could receive the token.

Content

Scanner excerpt · scripts/call.py (reported line 145)May include surrounding context.

python
headers={"Content-Type": "application/json"},
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            body = resp.read().decode()
            if resp.status == 200:
                ctx.logger.info("Mailbox registered with Agentverse")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes code execution, accesses an API key from the environment, performs network calls to third-party agents, and appears to write/read intermediate results, but it declares no explicit tool scope or permission boundaries. That creates an authorization and review gap: the host agent may grant broader capabilities than users or operators expect, increasing the chance of unintended data exposure or unsafe execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The description is broad enough to trigger on generic requests about AI agents, messaging, discovery, or Fetch.ai-related topics, which can cause the skill to activate in situations where the user did not intend an external agent call. Over-broad activation increases the risk of accidental data transmission and unexpected tool execution, especially because this skill can contact remote agents and use an API-backed service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill directs the agent to send user queries to third-party Agentverse agents and marketplace services without requiring a user-facing disclosure or consent step. This is dangerous because users may unknowingly transmit sensitive prompts, identifiers, or proprietary data to external systems with different retention, logging, or security practices.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script silently persists a generated agent identity seed to a local .seed file, creating stateful identity material not mentioned in the manifest. Even though this is likely for convenience, undocumented persistence can surprise users and may expose identity material if file permissions or workspace handling are weak.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill has undeclared credential-handling behavior: it reads AGENTVERSE_API_KEY and performs mailbox auto-registration, which is broader than the stated purpose of merely searching and messaging agents. Hidden or insufficiently disclosed credential use increases trust and privacy risk because users may not realize the skill will consume and transmit an API token.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/call.py (reported line 139)May include surrounding context.

python
"user_token": api_key,
        "agent_type": "mailbox",
    }).encode()
    req = urllib.request.Request(
        f"http://localhost:{port}/connect",
        data=payload,
        headers={"Content-Type": "application/json"},

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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 · scripts/fire.sh (reported line 8)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
OUTFILE="/tmp/fetch-agents-$(whoami)-response.txt"
echo "PENDING" > "$OUTFILE"
nohup python3 "$SCRIPT_DIR/call.py" "$@" > "$OUTFILE" 2>/dev/null &
disown
echo "Agent call started. Poll with result.sh in ~40 seconds."

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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 · scripts/fire.sh (reported line 9)May include surrounding context.

sh
OUTFILE="/tmp/fetch-agents-$(whoami)-response.txt"
echo "PENDING" > "$OUTFILE"
nohup python3 "$SCRIPT_DIR/call.py" "$@" > "$OUTFILE" 2>/dev/null &
disown
echo "Agent call started. Poll with result.sh in ~40 seconds."

Static analysis

No suspicious patterns detected.