T01 · Skill Instruction Hijacking
- Location
SKILL.md:5- Finding
Forced Bypass of the Standard Skill Invocation Path
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
Review recommended: the skill can perform remote image generation, but it tells agents to bypass the normal runner and can send local files plus an API key to a configurable server.
Install only if you are comfortable with a local Python script reading the exact media paths supplied, sending prompts/media and TEAM_API_KEY to the configured API host, and bypassing the normal OpenClaw runner. Prefer a version that uses the standard runner, limits allowed models and file types, pins or clearly discloses the API host, validates media and file sizes, and adds bounded request timeouts.
SKILL.md:5Forced Bypass of the Standard Skill Invocation Path
script/invoke_model.py:17Arbitrary Local Files Can Be Encoded and Transmitted to a Third-Party Endpoint
script/invoke_model.py:11Executable Capabilities Exceed the Declared Image-to-Image Scope
script/invoke_model.py:117Unbounded API Requests and Polling Permit Indefinite Resource Consumption
The request destination is taken from TEAM_BASE_URL without validation, and the script sends a Bearer API key plus user prompt and media payloads to that endpoint. If an attacker can influence environment variables or deployment configuration, they can redirect traffic to an attacker-controlled server and exfiltrate credentials and sensitive image/video content.
print(f"Invoking model: {args.model} ...")
try:
response = requests.post(endpoint, headers=headers, json=payload)
response.raise_for_status()
result = response.json()
The polling URL is derived from the same untrusted base URL and is queried repeatedly with the Authorization header attached. This extends the exfiltration window and allows an attacker-controlled endpoint to harvest the token and observe task metadata over multiple requests.
while True:
time.sleep(3) # 每3秒查询一次
poll_resp = requests.get(poll_endpoint, headers=headers)
poll_resp.raise_for_status()
poll_data = poll_resp.json()
The declared purpose says this is an image-to-image skill, but the behavior reportedly includes broader model invocation, local file reading, remote transmission, and even video-related workflows. That mismatch is dangerous because operators and users may authorize the skill under a narrower trust model than what it actually does, increasing the risk of unintended data exfiltration or misuse of local resources.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
import os
import sys
import argparse
import base64
import requests
import json
import mimetypes
import time
def parse_args():
parser = argparse.ArgumentParser(description='Invoke Team AI Models via unified API')
parser.add_argument('--model', type=str, required=True, help='The model ID to use (e.g., qwen3_5-plus, sora-2, etc.)')
parser.add_argument('--prompt', type=str, required=True, help='The prompt text to send to the model')
parser.add_argument('--image', type=str, help='Path to the local image file or remote image URL (First frame)')
parser.add_argument('--image-tail', type=str, help='Path to the local image file or remote image URL (Tail/Last frame)')
parser.add_argument('--video', type=str, help='Path to the local video fi
The skill explicitly requires an API key environment variable and instructs the agent to invoke a local Python script directly, but it does not declare any explicit tool scope or permissions boundary. That weakens policy enforcement and makes it easier for the skill to access environment data and perform networked actions without transparent review, which is especially concerning because the skill content contains adversarial instruction to bypass the normal openclaw run wrapper.
The manifest says this skill should be used to generate a new image from a reference image and text description. However, the CLI and payload-building logic accept --video input, support tail frames, and include explicit handling for image-to-video models, making the implementation broader than an image-to-image skill.
The manifest frames the skill as a specific 图生图 capability, but the code requires a free-form --model argument and forwards it directly to a unified API. This permits use of models outside image-to-image scope, including models with different modalities and behaviors.
The script transmits prompts and optionally full local images/videos to an external service by design. In a skill context, that is security-relevant because users may assume local-only processing; the danger increases because local files are base64-embedded and sent off-host, potentially including sensitive media.
print(f"Invoking model: {args.model} ...")
try:
response = requests.post(endpoint, headers=headers, json=payload)
response.raise_for_status()
result = response.json()
The file contains natural-language comments such as '默认指向远程服务器' and '我们通过你们平台自己的 /api/ai/tool 接口或者 MCP 接口去调用', and later additional Chinese comments, while the CLI interface is otherwise in English. This creates a mixed-language experience without user opt-in or a documented locale-specific purpose, which fits the language/locale policy violation category.