T01 · Skill Instruction Hijacking
- Location
bin/cli.js:323- Finding
Persistent Agent Identity Replacement and Persona Injection
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its selfie-companion purpose, but its installer persistently rewrites the agent’s identity/persona and stores a fal.ai API key locally, so users should review it before installing.
Install only if you want this package to alter the broader OpenClaw agent persona, not just add a selfie tool. Back up IDENTITY.md, SOUL.md, and openclaw.json first, use a pinned package version, review the exact destination before any send, and consider using a limited fal.ai key that can be rotated.
bin/cli.js:323Persistent Agent Identity Replacement and Persona Injection
SKILL.md:240Shell Command Injection in the Documented TypeScript Implementation
bin/cli.js:289Fal.ai API Key Stored Redundantly in Plaintext Configuration
The description claims the skill generates and sends selfies, but the provided code does not perform image generation or messaging-platform sending. Instead, it is an installer/setup script that configures an OpenClaw environment for such a skill. While these actions may support the declared feature, they are materially different from the stated primary purpose and involve undeclared local file/config modifications and credential handling. Therefore, the description does not accurately represent the actual behavior of this code chunk.
The core purpose mostly aligns: the script generates a Clawdy selfie image via fal.ai/xAI Grok Imagine and sends it over a messaging channel. However, the declaration is incomplete relative to behavior. The code explicitly performs messaging through the OpenClaw CLI to a provided channel, yet declared permissions are empty. It also depends on and uploads a bundled local reference image, enforcing identity-preserving edits rather than generic image generation, and it downloads the result to local temporary storage before sending. These are materially relevant resource/capability details absent from the declaration, so this should be flagged as a mismatch.
The description is close at a high level because the code does generate an image through fal.ai and send it to a messaging channel. However, the implementation materially differs in what it generates: it is explicitly a reference-image edit pipeline tied to a fixed local image (assets/clawdy.png) and heavily constrains the result to remain the same exact male person. That is not accurately represented by the broad description of generating selfies of 'Clawdy'. The sending behavior is also narrower than stated, using a specific openclaw CLI channel send path rather than a general multi-platform abstraction. Additionally, the skill uses undeclared resources/permissions such as reading a local asset, writing a temp file, invoking a subprocess, and requiring the FAL_KEY secret. These are meaningful capability/resource mismatches, so this should be flagged.
The code broadly aligns with the stated purpose of generating and sending Clawdy selfies using xAI Grok Imagine via fal.ai. However, the declared permissions are empty, while the code clearly performs messaging/file sending through openclaw message send, accesses a bundled reference image, writes a temporary local file, and calls an external API using the FAL_KEY credential. Those are undeclared resource/capability accesses under the evaluation criteria. The primary purpose is accurate, but the permissions/capabilities disclosure is incomplete, so this should be flagged as a mismatch.
The code broadly aligns with the declared high-level purpose of generating and sending selfie images via fal.ai across messaging channels. However, the implementation materially narrows and changes the subject: it performs reference-image editing of a fixed male person and aggressively preserves that exact human identity, which is not clearly conveyed by the description 'selfies of Clawdy.' In addition, the code accesses local files (reads a bundled reference image, writes output to /tmp) and uses an external CLI to send the message/file, while the declared permissions are empty. Those resource accesses and messaging mechanisms are undeclared capabilities. So this is a partial but meaningful description/behavior mismatch.
The skill uses 'shell' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.
The file contains natural-language instructions mandating generation from the same male reference image, and later prompt text reinforces 'clearly male' and excludes female presentation. This imposes a fixed gender/identity constraint without user opt-in or documented justification, which is a natural-language policy concern.
The BASE_LOCK string includes explicit directives such as 'clearly male', 'do not feminize', 'not female', and 'not woman'. This is a natural-language policy violation because it forces a specific identity/presentation without offering user choice or stating a justified regional/compliance need.
The script reads a secret from the environment (FAL_KEY) but the analysis indicates that environment access is not declared in permissions. Undeclared secret access weakens transparency and permission boundaries, making it easier for a skill to use sensitive credentials without clear user or platform review.
The skill is described as generating selfies of Clawdy, but the prompt logic instead forces preservation of a specific human male identity. This mismatch is dangerous because it can mislead reviewers and users about what content is being generated and sent externally, undermining informed consent and trust.
The prompt hard-codes a gendered identity and explicitly excludes women, despite the skill being framed as generating Clawdy selfies. This is not a classic exploit primitive, but it is a harmful hidden behavior that can mislead users, encode biased output constraints, and indicate the tool is being used for undisclosed human-image generation rather than its stated purpose.
The README instructs users to execute npx clawdy@latest, which fetches and runs the latest published package without pinning a version or integrity value. If the npm package is compromised, typo-squatted, or a malicious update is published, users could execute attacker-controlled code during installation with their local user privileges.
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.
### 1. Get a fal.ai API Key
Visit [fal.ai/dashboard/keys](https://fal.ai/dashboard/keys) and create one.
### 2. Clone the Skill
The description does not clearly warn that prompts and the reference image URL are transmitted to fal.ai and that generated media is then sent to third-party messaging platforms. This lack of disclosure increases the chance of users providing sensitive context without understanding that it leaves the local environment.
The trigger phrases are overly broad everyday language such as 'what are you doing?' and 'how are you doing?', which can cause the skill to activate unintentionally. In this skill's context, accidental activation can leak user context to fal.ai and send generated media to external messaging destinations without sufficiently explicit user intent.
This skill transmits user-derived prompt content and the reference image URL to an external service, fal.ai. While external API use is part of the feature, it is still a real data-exposure boundary crossing that can disclose sensitive user context if the prompt contains personal, confidential, or regulated information.
--arg prompt "$PROMPT" \
'{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')
curl -X POST "https://fal.run/xai/grok-imagine-image/edit" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD"
The complete script performs the same external transmission in executable form, sending user-influenced prompt data to fal.ai over the network. Because the skill also supports broad triggers and downstream messaging, accidental or overly permissive use increases the privacy and data-handling risk.
--arg prompt "$EDIT_PROMPT" \
'{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')
RESPONSE=$(curl -s -X POST "https://fal.run/xai/grok-imagine-image/edit" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD")
The TypeScript example constructs a shell command with user-controlled channel and caption values inside a single command string passed to child_process.exec. An attacker who can influence those values may inject shell metacharacters and execute arbitrary local commands with the privileges of the agent process.
Natural-language strings throughout the file define the skill as 'Your Boyfriend' and later reinforce this persona with 'He's ready' and identity content. This imposes a specific relational/gendered persona by default rather than offering the user a choice, which is a natural-language policy concern around forced persona/locale-style defaults.
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.
The installer stores the supplied FAL_KEY in plaintext in ~/.openclaw/openclaw.json under both apiKey and env.FAL_KEY without clearly warning the user that the credential will be persisted on disk. Plaintext secret persistence increases the blast radius of local compromise, backups leakage, config sharing, or accidental exposure through logs and support bundles.
The installer modifies IDENTITY.md and SOUL.md, changing the host agent's identity and behavior beyond what is required to enable selfie generation. This creates an integrity and consent problem: installing a media skill silently rewrites core agent persona, which can mislead users and persistently alter future agent behavior.
writeIdentity() overwrites the agent identity with a fixed persona ('Clawdy', 'Your boyfriend') unrelated to the minimum functional requirement of sending generated selfies. A skill installer should not unilaterally redefine the host assistant's identity because that can manipulate user trust, alter downstream responses, and create persistent deceptive behavior.
The generated IDENTITY.md forces a specific intimate relationship role ('Your boyfriend') and personality without user opt-in. In context, this is more dangerous because it persistently alters the agent's social framing, potentially misleading users and changing future interactions in ways unrelated to the advertised selfie capability.
injectPersona() appends behavioral instructions to SOUL.md that steer when and how the agent should present itself visually and socially, which exceeds simple image-generation setup. Persistently injecting broad behavior rules into a global soul/persona file can influence unrelated interactions and is dangerous because it changes the system's decision-making without strong user consent.
Detected: suspicious.dangerous_exec, suspicious.env_credential_access