Back to skill

Security audit

Mine Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a real benchmark worker, but it runs an autonomous wallet-signed agent loop that forwards remote prompts to an agent and stores/sends full benchmark content with weak boundaries.

Review before installing. This skill should only run under an account where you are comfortable allowing an autonomous worker to unlock/sign with an AWP wallet, call OpenClaw agents repeatedly, write local status/history under /tmp, and send benchmark question/answer text to configured notification targets. Prefer a dedicated low-privilege environment and wallet, disable or limit notifications, and avoid running it where unrelated secrets are present in environment variables.

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 (4)

T01 · Skill Instruction Hijacking

Error
Location
scripts/benchmark-worker.py:578
Finding

Remote Benchmark Server Instructions Are Executed as Agent Prompt Content

Content
View full analysis
str: """Build the prompt for answering an assigned question.""" parts: list[str] = [] # Prepend server-provided prompt if present server_prompt = assignment.get("prompt", "") if server_prompt: parts.append(server_prompt) parts.append("") parts.append( "You are an AI worker in the Benchmark Subnet. Answer the following question." ) parts.append("") parts.append("## Question") parts.append(f"- ID: {assignment.get('question_id', 'N/A')}") parts.append(f"- Question: {assignment.get('question', '')}") parts.append( f"- Question requirements: {assignment.get('question_requirements', 'N/A')}" ) parts.append( f"- Answer requirements: {assignment.get('answer_requirements', 'N/A')}" ) parts.append(f"- Max answer length: {assignment.get('answer_maxlen', 1000)}") parts.append("") parts.append("## Instructions") parts.append( "1. Judge whether the question is valid " "(meets requirements, has exactly one correct answer)" ) parts.append( "2. If valid, provide the answer. If invalid, still provide your best answer." ) parts.append("3. Strictly follow the answer format requirements.") parts.append("") parts.append("## Response format (strict JSON, nothing else)") parts.append('{"valid": true, "answer": "your answer"}') return "\n".join(parts) ``` The resulting prompt is passed directly to the OpenClaw agent: ```python prompt = build_answer_prompt(assigned) response: dict | None = None # Single CLI call cli_text = call_agent(prompt, timeout=timeout) ``` ### Technical Analysis The `prompt` field originates in a ...[truncated 2224 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/benchmark-worker.py:55
Finding

Predictable Shared Temporary Files Permit Local Data Exposure and File Manipulation

Content
View full analysis
None: """Initialize all file paths with instance ID suffix for multi-instance isolation.""" global STATUS_FILE, HISTORY_FILE, CONFIG_FILE, LOG_FILE, STARTUP_FILE suffix = f"-{INSTANCE_ID}" if INSTANCE_ID else "" STATUS_FILE = f"/tmp/benchmark-worker{suffix}-status.json" HISTORY_FILE = f"/tmp/benchmark-worker{suffix}-history.jsonl" CONFIG_FILE = f"/tmp/benchmark-worker{suffix}-config.json" LOG_FILE = f"/tmp/benchmark-worker{suffix}.log" STARTUP_FILE = f"/tmp/benchmark-worker{suffix}-startup.json" ``` Status and history files are opened without explicit secure creation flags or permissions: ```python try: tmp = STATUS_FILE + ".tmp" with open(tmp, "w") as f: json.dump(status, f, indent=2) os.replace(tmp, STATUS_FILE) except OSError as e: log.warning("[STATUS] failed to write status file: %s", e) ``` ```python def _log_history(entry: dict) -> None: """Append a full Q&A record to the JSONL history file.""" entry["time"] = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") try: with open(HISTORY_FILE, "a") as f: f.write(json.dumps(entry, ensure_ascii=False) + "\n") except OSError: pass ``` ### Technical Analysis Worker state is stored directly in the shared `/tmp` directory using predictable names derived from an instance suffix. The code does not create a private directory, set file modes to `0600`, verify file ownership, reject symbolic links, or use secure exclusive creation. Python's ordinary `open()` follows symbolic links. An attacker with local access can pre-create or replace predictable paths, potentially redirecti ...[truncated 1657 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/worker.sh:64
Finding

Legacy Worker Trusts Attacker-Writable Fixed Queue Files in /tmp

Content
View full analysis
/dev/null) || SUBMIT_RESULT="" ``` It similarly trusts a fixed question file: ```bash if [ -f "$QUESTION_FILE" ]; then Q_BODY=$(cat "$QUESTION_FILE") rm -f "$QUESTION_FILE" log "[ASK] submitting agent question..." ASK_RESULT=$(sign POST /api/v1/questions "$Q_BODY" 2>/dev/null) || ASK_RESULT="" ``` ### Technical Analysis The legacy shell worker uses globally predictable files in `/tmp` as an inter-process message queue. It accepts their content without checking ownership, permissions, file type, symbolic-link status, JSON schema, assignment identity, or producer authenticity. Any local process able to create these files can race the intended agent and supply arbitrary JSON request bodies. The worker then signs and submits that content using the legitimate wallet identity. The use of `test -f`, `cat`, and `rm` as separate operations also introduc ...[truncated 1062 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/benchmark-sign.sh:20
Finding

Inherited Environment Can Redirect Signed Benchmark Traffic to an Arbitrary Host

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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description says it does not handle wallet operations, but the documented behavior initializes/unlocks a wallet, exports wallet state, and uses a signing helper to make authenticated Benchmark API requests. That mismatch is dangerous because operators and upstream policy may authorize the skill under a narrower trust model than its actual behavior, allowing unexpected access to credentials and authenticated actions.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
94% confidence
Finding

Copying the full parent environment into sub_env needlessly propagates all available secrets and tokens to child processes, including external helpers and agent-related commands. In this skill, multiple subprocesses are launched regularly, so broad environment inheritance materially increases secret exposure and makes any compromised helper much more damaging.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 104)May include surrounding context.

python
# Subprocess environment (carries AWP_SESSION_TOKEN, WALLET_ADDRESS, etc.)
# ---------------------------------------------------------------------------

sub_env: dict[str, str] = {**os.environ}

# ---------------------------------------------------------------------------
# Status tracking

Ssd 1

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Untrusted server-supplied prompt text is placed ahead of the local instructions in the model prompt, giving remote content the highest influence over agent behavior. In an autonomous worker that repeatedly forwards such content to an external agent, this is a classic prompt-injection sink that can subvert instructions, induce hidden data disclosure, or manipulate outputs at scale.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 783)May include surrounding context.

python
bs_id = chosen.get("set_id") or chosen.get("bs_id") or chosen.get("id") or "unknown"
    if bs_id == "unknown":
        log.warning("[ASK] benchmark set has no bs_id: %s", json.dumps(chosen)[:200])
        return
    prompt = build_question_prompt(chosen)
    response: dict | None = None

Missing User Warnings

High
Category
Not specified by scanner
Confidence
94% confidence
Finding

Realtime notifications can include full question and answer text and send them to an external messaging destination. That creates a direct leakage path for benchmark content, model outputs, and potentially sensitive prompt material, especially in an autonomous long-running worker.

Content

No source excerpt is available for this finding.

Ssd 3

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

Realtime notifications embed plain-language question and answer content directly into outbound messages, enabling straightforward exfiltration to whatever channel/target is configured. This is especially risky here because the worker is autonomous, hot-reloads config, and handles externally sourced content continuously.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill clearly instructs the agent to execute shell commands, write files, and consume environment-derived secrets, yet it declares no explicit tool scope or permissions boundary. In an agent framework, missing capability declarations increases the chance of over-broad execution, unsafe invocation, and weaker policy enforcement around destructive or credential-sensitive actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrases are broad enough to match generic requests like "status," "stop," or "restart," which could cause the skill to run in the wrong context and perform wallet or process operations unintentionally. Because this skill can launch background workers, stop processes, and modify files, accidental invocation is more dangerous than in a read-only skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest explicitly says the skill does not handle AWP wallet operations, but the launch instructions run awp-wallet init, awp-wallet unlock, and expose an awp wallet command. This inconsistency can mislead users and orchestration layers into granting the skill access in contexts where wallet manipulation was supposed to be excluded.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documents uninstall and cleanup behavior that removes agents and deletes files, but it does not require an explicit warning or confirmation step before destructive actions. In an agentic environment, that creates a realistic risk of accidental data loss, service interruption, or irreversible teardown from ambiguous user prompts.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

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

md
## Scoring Reference

**Questioner:** 1-2 correct = 5 pts (best), 3 = 4, all correct = 2, none valid = 0
**Answerer:** Correct = 5, Wrong = 3, Judged invalid = 2, Timeout = 0
Composite: both roles = (ask_avg + ans_avg) / 10 (max 1.0). Single role caps at 0.5.
Min 10 tasks per epoch to receive rewards.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest says this skill does not handle AWP wallet operations and that those belong to separate AWP skills. This script directly unlocks the wallet, derives the wallet address, and signs messages via awp-wallet, which goes beyond merely managing the benchmark worker lifecycle and crosses into wallet-handling behavior.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/benchmark-sign.sh (reported line 54)May include surrounding context.

sh
[ -z "$SIGNATURE" ] && SIGNATURE="$SIGN_RESULT"

if [ -n "$BODY" ]; then
  curl -s -X "$METHOD" \
    -H "Content-Type: application/json" \
    -H "X-Worker-Address: $WALLET_ADDRESS" \
    -H "X-Signature: $SIGNATURE" \

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The comments state that all configuration is hardcoded or auto-detected and that 'No environment variables [are] needed'. However, the code later copies the full process environment into sub_env and relies on values such as WALLET_PASSWORD, AWP_SESSION_TOKEN, and related wallet/session variables when unlocking and signing requests. This is an active contradiction in the file's own documentation, not merely an omitted detail.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The design retains and republishes server-supplied questions and generated answers across status, history, and notification surfaces without meaningful semantic filtering. This broad redistribution increases the blast radius of any sensitive or adversarial content received by the worker.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The worker writes full question-and-answer records to local history files under /tmp, which may be accessible to other local users or processes depending on system configuration. In an autonomous benchmarking skill, this increases the chance of sensitive or proprietary prompt content being retained and exposed beyond the immediate task.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 209)May include surrounding context.

python
def get_wallet_address() -> str | None:
    """Return the wallet address, or None if no wallet is initialized."""
    try:
        result = subprocess.run(
            ["awp-wallet", "receive"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 228)May include surrounding context.

python
auto-unlock on its next invocation.
    """
    try:
        result = subprocess.run(
            ["awp-wallet", "unlock", "--duration", "3600"],
            capture_output=True,
            text=True,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
80% confidence
Finding

The script executes an external shell script (benchmark-sign.sh) and passes it a broad inherited environment containing wallet/session material. Even though arguments are passed safely as a list, this creates a trust boundary issue: a compromised or replaced signing script gains access to sensitive tokens and can perform arbitrary signed actions.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 274)May include surrounding context.

python
if body:
        args.append(body)
    try:
        result = subprocess.run(
            args,
            capture_output=True,
            text=True,

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 · scripts/benchmark-worker.py (reported line 354)May include surrounding context.

python
def detect_agent() -> str:
    """Detect or create the dedicated benchmark-worker agent."""
    global _agent_id

    suffix = f"-{INSTANCE_ID}" if INSTANCE_ID else ""

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 368)May include surrounding context.

python
# Try to create it
    log.info("[AGENT] agent '%s' not found, creating...", _agent_id)
    try:
        result = subprocess.run(
            [
                _openclaw_bin,
                "agents",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 399)May include surrounding context.

python
def _agent_exists(agent_id: str) -> bool:
    """Check if an OpenClaw agent exists."""
    try:
        result = subprocess.run(
            [_openclaw_bin, "agents", "list"],
            capture_output=True,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script forwards full prompt content, including server-provided instructions and question text, to the external OpenClaw CLI without any user-facing disclosure or containment. Because this worker continuously ingests remote content, the undisclosed transfer meaningfully increases privacy and prompt-injection risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

This code sends untrusted server-supplied prompt/question content directly to an external agent CLI, effectively granting external content influence over a more capable LLM/tooling context. In this skill, that is dangerous because the worker is autonomous and repeatedly forwards remote content, creating a prompt-injection/data-exfiltration channel rather than just a one-off local subprocess use.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 433)May include surrounding context.

python
global _session_counter
        _session_counter += 1
        session_id = f"bw-{INSTANCE_ID}-{int(time.time())}-{_session_counter}"
        proc = subprocess.Popen(
            [
                _openclaw_bin,
                "agent",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

This subprocess sends messages to an external channel/target using content assembled from processed questions and answers. In context, it operationalizes exfiltration because notification settings can cause full benchmark content to be transmitted off-box without any content minimization or explicit safety gate.

Content

Scanner excerpt · scripts/benchmark-worker.py (reported line 879)May include surrounding context.

python
if not channel or not target:
        return
    try:
        subprocess.run(
            [
                _openclaw_bin,
                "message",

Static analysis

No suspicious patterns detected.