T09 · Insecure Skill Coding Practices
- Location
run.sh:7- Finding
Arbitrary Code Execution Through Shell-Sourced Credential File
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly matches its Amazon listing and optional image-generation purpose, but it also has under-disclosed credential, logging, recipient-discovery, and outbound messaging behavior that users should review carefully.
Install only if you are comfortable with product details, prompts, image URLs, and configured API credentials being sent to external model/image services, and review the Feishu recipient-routing behavior before enabling image generation. Use tightly scoped keys, avoid shared or writable skill directories, do not put untrusted content in .env, and rotate any image workflow key if this version has already run with logging enabled.
run.sh:7Arbitrary Code Execution Through Shell-Sourced Credential File
modules/coze_generate_image.py:34Image Workflow Credential and User Metadata Persisted in Plaintext Logs
modules/coze_generate_image.py:134OpenClaw Terminal Pane Scraping to Discover Feishu User and Chat Identifiers
skill.py:213API Credentials and User Data Can Be Sent to Unrestricted Configurable Endpoints
The destination URL and bearer token are environment-controlled, and user prompt data is transmitted to that endpoint without in-code trust restrictions. If the environment is misconfigured or attacker-controlled, prompts and workflow data can be exfiltrated to an arbitrary external service along with sensitive credentials or metadata.
}
)
with urllib.request.urlopen(req, timeout=120) as resp:
return json.loads(resp.read().decode("utf-8"))
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
bash ~/.openclaw/workspace/skills/amazon-listing-factory/run.sh "生成listing:充电宝,美国站,突出便携、大容量、安全感,输出6张图"
如需自动生图,请先配置 .env 中的图片环境变量,并前往米核获取 KEY:
miheai.com/s/98707
The documented purpose is Amazon listing generation, but the observed behavior includes external API calls, image generation, recipient identification via environment/tmux inspection, outbound delivery to Feishu, and runtime logging. This hidden functionality creates a serious trust boundary violation: users may provide commercial content or sensitive data for copywriting while the skill silently performs networked side effects and user-context discovery unrelated to the stated task.
The code enumerates many environment variables and even inspects tmux session output to infer current messaging recipients and chat context. For an Amazon listing draft skill, this is unjustified access to operational/user metadata and enables unintended message targeting, privacy violations, and cross-context data leakage.
The skill does more than generate listing-related content: it auto-routes generated images and sends them to Feishu recipients. This hidden messaging capability is outside the declared skill purpose, making data exfiltration and unauthorized outbound communication much more dangerous because users and operators would not expect it.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
INPUT="${1:-}"
if [ -f "$SKILL_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
source "$SKILL_DIR/.env"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
INPUT="${1:-}"
if [ -f "$SKILL_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
source "$SKILL_DIR/.env"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
INPUT="${1:-}"
if [ -f "$SKILL_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
source "$SKILL_DIR/.env"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
INPUT="${1:-}"
if [ -f "$SKILL_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
source "$SKILL_DIR/.env"
The script sources $SKILL_DIR/.env directly into the shell, which executes any shell syntax contained in that file, not just key-value assignments. If an attacker can modify the .env file or influence its contents, this becomes arbitrary code execution in the context of whoever runs the skill; in a skill environment that may also expose secrets as exported variables to child processes.
if [ -f "$SKILL_DIR/.env" ]; then
set -a
# shellcheck disable=SC1091
source "$SKILL_DIR/.env"
set +a
fi
The skill automatically creates and reads a plaintext .env file in the skill directory for API keys and tokens, encouraging long-lived credential storage alongside code. In shared or weakly permissioned environments, those secrets can be exposed through filesystem access, backups, packaging, or accidental publication, and this skill uses multiple external-service credentials that could enable unauthorized API use.
def ensure_env_file():
skill_dir = Path(__file__).resolve().parent
env_file = skill_dir / ".env"
env_template = skill_dir / "ENV_TEMPLATE.txt"
if env_file.exists():
return env_file
This markdown file contains user-facing instructions entirely in Chinese, including the recommended slash command usage and local test examples. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly justified.
This markdown file contains user-facing operational instructions entirely in Chinese, including the recommended invocation example. Under the policy rule for natural-language violations, forcing a specific language without user opt-in can exclude users and conflicts with language/locale choice expectations.
The README content and invocation examples are entirely in Chinese, including the prescribed slash command input, with no indication that other languages are supported or that Chinese is a required locale for a justified reason. This can violate language/locale policy when a skill implicitly mandates one language without user opt-in.
The README states that the skill may automatically generate images if an image environment is configured, but it does not disclose whether this uses external models or APIs, what data is transmitted, or whether charges may be incurred. In a content-generation skill, this can lead to unexpected data exposure and unanticipated cost-bearing actions by users who believe they are only generating text drafts.
The skill advertises no explicit tool restrictions even though it appears capable of using shell, filesystem, environment inspection, and network access. In an agent setting, missing scope declarations weakens least-privilege controls and can allow broader-than-expected actions if the skill is invoked with sensitive context or elevated runtime permissions.
The instructional content and invocation examples from L18 onward are written only in Chinese, including the recommended command usage. This imposes a language expectation without opt-in or explanation that the skill is region-specific, which matches the language/locale policy violation criteria.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
WORKFLOW_ID = os.environ.get("COZE_WORKFLOW_ID", "").strip()
COZE_TOKEN = os.environ.get("COZE_TOKEN", "").strip()
COZE_API_URL = os.environ.get("COZE_API_URL", "https://api.coze.cn/v1/workflow/run").strip()
DEFAULT_RATIO = "1:1"
DEFAULT_RESOLUTION = "1K"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
WORKFLOW_ID = os.environ.get("COZE_WORKFLOW_ID", "").strip()
COZE_TOKEN = os.environ.get("COZE_TOKEN", "").strip()
COZE_API_URL = os.environ.get("COZE_API_URL", "https://api.coze.cn/v1/workflow/run").strip()
DEFAULT_RATIO = "1:1"
DEFAULT_RESOLUTION = "1K"
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
WORKFLOW_ID = os.environ.get("COZE_WORKFLOW_ID", "").strip()
COZE_TOKEN = os.environ.get("COZE_TOKEN", "").strip()
COZE_API_URL = os.environ.get("COZE_API_URL", "https://api.coze.cn/v1/workflow/run").strip()
DEFAULT_RATIO = "1:1"
DEFAULT_RESOLUTION = "1K"
The code captures content from a live tmux pane to infer who most recently sent a message, effectively scraping unrelated runtime/session data to obtain recipient identifiers. In this skill context, that behavior exceeds the stated Amazon listing draft purpose and can leak or misuse chat metadata from another process, creating a privacy and unauthorized-routing risk.
def detect_runtime_receive_target_from_tmux():
try:
proc = subprocess.run(
["tmux", "capture-pane", "-pt", "openclaw", "-S", "-300"],
capture_output=True,
text=True,
The debug snapshot reveals which secrets are configured and returns runtime recipient-target metadata, providing attackers with operational intelligence about the environment. Even when values are partially masked by booleans, this materially aids reconnaissance and can expose user-routing context unrelated to the skill's purpose.
The code sends user-provided prompts and reference image URLs to an external image-generation service without any in-code notice, minimization, or consent flow. While external processing may be functionally necessary, it is still a real data-sharing behavior that can expose proprietary product information or user-supplied media.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
]
try:
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
except Exception as e:
return {"ok": False, "error": "调用飞书发送脚本异常", "details": str(e)}
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
]
try:
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=180)
except Exception as e:
return {"ok": False, "error": "调用飞书发送脚本异常", "details": str(e)}