Back to skill

Security audit

Agent Profile Images

Security checks for vulnerabilities and agentic risk

Overview

The avatar feature is mostly coherent, but the package includes broad OpenClaw control-plane source snapshots with unrelated admin, secrets, update, and agent-management code that should be reviewed before installation.

Install only after reviewing the referenced source snapshots as a broad OpenClaw gateway/UI change, not as a narrow avatar-only patch. Confirm the installer or maintainer applies only the avatar-related diffs, disclose OpenAI data sharing to users, and harden avatar upload validation before using this in a shared or exposed gateway.

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

T09 · Insecure Skill Coding Practices

Warning
Location
references/src-gateway-server-methods-agents-ts.txt:440
Finding

Avatar uploads trust client-controlled file type metadata without validating image content

Content
View full analysis
; agentId: string; bytes: Buffer; extension: string; }): Promise<{ avatar: string; avatarUrl: string }> { const workspace = resolveAgentWorkspaceDir(params.cfg, params.agentId); const avatarDir = path.join(workspace, "avatars"); await fs.mkdir(avatarDir, { recursive: true }); const filename = `profile${params.extension}`; const absolutePath = path.join(avatarDir, filename); await fs.writeFile(absolutePath, params.bytes); const identityPath = path.join(workspace, DEFAULT_IDENTITY_FILENAME); await fs.appendFile(identityPath, `\n- Avatar: avatars/${filename}\n`, "utf-8"); return { avatar: `avatars/${filename}`, avatarUrl: `/avatar/${params.agentId}`, }; } ``` The corresponding upload handler derives the extension entirely from request metadata: ```ts const decoded = decodeAvatarUploadData(String(params.data ?? "")); if (!decoded || decoded.bytes.length === 0) { respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "invalid avatar image data")); return; } if (decoded.bytes.length > 2 * 1024 * 1024) { respond(false, undefined, errorShape(ErrorCodes.INVALID_REQ ...[truncated 2946 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
references/src-gateway-server-methods-agents-ts.txt:424
Finding

Avatar size enforcement occurs only after unbounded base64 input is decoded

Content
View full analysis
2 * 1024 * 1024) { respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "avatar image exceeds 2MB limit")); return; } ``` ### Technical Analysis The intended 2 MB restriction applies only to the resulting `Buffer`. Before reaching that check, the gateway must receive ...[truncated 2165 chars]
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (22)

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The schema for this skill exposes capabilities far beyond profile-image handling, including agent creation, update, deletion, file listing/get/set, skill installation/update, and tool catalog access. In a skill whose stated purpose is avatar upload/generation, this mismatch creates an unnecessary expansion of the attack surface and enables privilege abuse if the skill is invoked or granted broadly.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file implements agent creation, update, deletion, and workspace file read/write operations even though the skill is presented as profile image management. In context, this is dangerous because users or reviewers may grant trust appropriate for avatar features while unknowingly exposing powerful filesystem and lifecycle controls over agents.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This skill is described as handling agent profile images, but the file also exposes a broad AI wizard that uses model credentials, accepts arbitrary user descriptions, and generates agent configuration content. That scope expansion materially increases attack surface and data flow beyond the declared purpose, making it easier to smuggle sensitive capabilities into a seemingly low-risk skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The wizard code resolves provider API keys and sends non-image prompts to external LLM APIs, which is unrelated to profile-image handling. Access to stored model credentials in an unexpectedly broad skill raises the risk of unauthorized external data transmission and hidden use of privileged authentication material.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest describes a narrowly scoped skill for uploading, generating, previewing, and persisting agent profile images. This file registers a much wider set of operations including config changes, secrets management, node/device pairing, cron control, session deletion, approvals, updates, browser requests, and general agent/chat methods, which materially exceed avatar-related behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Methods for listing, writing, deleting, migrating, and resolving secrets are not a direct or obvious requirement for uploading or generating profile images. Exposing secret-handling functionality in a profile image skill grants access to sensitive capabilities unrelated to the manifest's stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Node pairing, device token management, remote node invocation, and cron administration are infrastructure-control functions unrelated to avatar upload/generation workflows. These capabilities are not justified by the manifest's narrow UI-oriented image-management purpose.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
95% confidence
Finding

The UI sends a chat instruction that explicitly tells the agent to follow a local skill for upstream merge/update operations, including AI-assisted merge and commit phases. This creates a self-modification pathway where an LLM-driven agent can alter local code/configuration based on natural-language prompting, increasing the risk of prompt injection, unsafe code changes, or persistence of malicious modifications if an attacker can influence the conversation or the referenced skill.

Content

Scanner excerpt · references/ui-src-ui-app-render-ts.txt (reported line 949)May include surrounding context.

text
? ` Use model ${state.mergeModel} for conflict resolution (set SAFE_MERGE_MODEL=${state.mergeModel}).`
              : "";
            void state.handleSendChat(
              `Run a safe upstream merge update now. Follow the safe-merge-update skill at ~/.openclaw/workspace/skills/safe-merge-update/SKILL.md — run all 4 phases (preflight, AI merge, validate, commit). Report progress as you go.${modelNote}`,
            );
            setTimeout(() => {
              state.updateInProgress = false;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly advertises AI avatar generation through OpenAI Images but does not warn users that prompts and possibly uploaded or generated content may be sent to a third-party provider. This can lead to unintended disclosure of personal, sensitive, or proprietary information if users include identifying details in generation prompts or source images.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Avatar generation sends agent-derived fields such as name, emoji, theme, and optional instructions to OpenAI. In a profile-images skill this is contextually relevant, but without explicit disclosure/consent and clear indication of what metadata leaves the system, it creates a real privacy and policy risk through external transmission.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The hardcoded OpenAI endpoint confirms that avatar generation depends on a third-party service. While not inherently malicious, it is a genuine data egress point and should be treated as such, especially because the skill also contains broader-than-advertised functionality.

Content

Scanner excerpt · references/src-gateway-server-methods-agents-ts.txt (reported line 510)May include surrounding context.

text
.filter(Boolean)
    .join(" ");

  const response = await fetch("https://api.openai.com/v1/images/generations", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

The hardcoded OpenAI endpoint confirms that avatar generation depends on a third-party service. While not inherently malicious, it is a genuine data egress point and should be treated as such, especially because the skill also contains broader-than-advertised functionality.

Content

Scanner excerpt · references/src-gateway-server-methods-agents-ts.txt (reported line 510)May include surrounding context.

text
.filter(Boolean)
    .join(" ");

  const response = await fetch("https://api.openai.com/v1/images/generations", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The agents.delete handler can remove an agent's workspace, agent directory, and session transcripts by moving them to trash when deleteFiles is true, but this path contains no confirmation prompt or user-facing disclosure about those filesystem effects. For a destructive operation affecting user data, the code only performs the action and returns success, which fits the missing-warning criterion for code files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The wizard endpoint transmits free-form user descriptions to Anthropic or OpenAI, which may include sensitive operational or personal data. Because this capability is outside the declared profile-image scope, the hidden external sharing is more dangerous and likely to violate user expectations and trust boundaries.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This outbound call to Anthropic is part of the unrelated wizard functionality, sending user-supplied descriptions and using resolved API credentials. In a profile-images skill, that hidden network capability significantly increases risk because it enables external transmission of arbitrary text under unexpectedly broad trust.

Content

Scanner excerpt · references/src-gateway-server-methods-agents-ts.txt (reported line 1122)May include surrounding context.

text
const headers: Record<string, string> = { "Content-Type": "application/json" };

      if (provider === "anthropic") {
        url = "https://api.anthropic.com/v1/messages";
        headers["x-api-key"] = auth.apiKey;
        headers["anthropic-version"] = "2023-06-01";
        body = {

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This OpenAI chat completions call supports the non-image wizard feature and sends arbitrary user descriptions to an external provider using stored credentials. Because it is outside the stated purpose of the skill, it represents undeclared external exfiltration potential and hidden privilege use.

Content

Scanner excerpt · references/src-gateway-server-methods-agents-ts.txt (reported line 1133)May include surrounding context.

text
};
      } else {
        // OpenAI-compatible
        url = "https://api.openai.com/v1/chat/completions";
        headers["Authorization"] = `Bearer ${auth.apiKey}`;
        body = {
          model: modelStr.replace(`${provider}/`, ""),

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The presence of a generic "browser.request" method suggests arbitrary browser-mediated network access. A profile image skill may reasonably upload or generate images, but a generic request capability is broader than necessary and is not explicitly justified by the manifest description.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · references/ui-src-ui-app-render-ts.txt (reported line 949)May include surrounding context.

text
? ` Use model ${state.mergeModel} for conflict resolution (set SAFE_MERGE_MODEL=${state.mergeModel}).`
              : "";
            void state.handleSendChat(
              `Run a safe upstream merge update now. Follow the safe-merge-update skill at ~/.openclaw/workspace/skills/safe-merge-update/SKILL.md — run all 4 phases (preflight, AI merge, validate, commit). Report progress as you go.${modelNote}`,
            );
            setTimeout(() => {
              state.updateInProgress = false;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code issues an agents.delete request, which is a destructive operation, but the user-facing confirmation at L1893-L1896 only asks for confirmation and does not explain consequences such as agent removal side effects or data loss. In this file there is no accompanying comment, docstring, or disclosure describing what deletion entails beyond a generic failure message.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The code directly requests gateway.restart, which can interrupt service and active sessions, but this file provides no warning, confirmation, or explanatory comment around that action. Because restart affects system availability, users should be explicitly informed before it occurs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This separate restart path also calls gateway.restart without any visible confirmation, warning text, or inline explanation in the file. The action is safety-relevant because it can disrupt running operations and connectivity.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The default Discord voice configuration sets transcribeLanguage to "en", which imposes a specific language choice in natural-language-facing behavior. In this file there is no accompanying comment or user-facing explanation indicating that the language is optional, user-selectable, or required for a documented region-specific purpose.

Content

No source excerpt is available for this finding.