T09 · Insecure Skill Coding Practices
- Location
scripts/clawdy-selfie.ts:147- Finding
Shell Command Injection Through OpenClaw CLI Arguments
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly fits a Clawdy selfie workflow, but it also includes under-disclosed video generation, third-party uploads, channel posting, and unsafe command execution paths that need review before installation.
Review this skill before installing. It can send generated media to OpenClaw channels and includes an under-disclosed video workflow that uploads the reference image to third-party hosts and uses a separate API key. Only run it with tightly scoped credentials, trusted prompts/channels, and after fixing the command-injection and temporary-file cleanup issues.
scripts/clawdy-selfie.ts:147Shell Command Injection Through OpenClaw CLI Arguments
scripts/clawdy-video.sh:65Undocumented Upload of the Identity Reference Image to Public File Hosts
scripts/clawdy-video.sh:18API Credential Transmission to an Arbitrary Configurable Service Origin
scripts/clawdy-selfie.sh:105Generated Selfie Retained in Predictable Shared Temporary Storage
scripts/clawdy-video.sh:262Generated Video Retained in Predictable Shared Temporary Storage
The description only says the skill generates a Clawdy selfie using a local helper script and FAL_KEY. The code does generate an image, but it also performs additional material actions not disclosed: it requires a channel argument, downloads the generated image to a local file, and sends that file plus a caption to an OpenClaw channel. That outbound messaging capability is not implied by mere 'generation' and should be declared. The code also specifically edits a fixed bundled reference image into a selfie and enforces a locked male identity, which is a meaningful behavior detail absent from the description. This is therefore a description/behavior mismatch.
The declared description is too narrow and omits significant behavior. The code is not a simple local helper that generates a specific 'Clawdy selfie'; it is a general-purpose image generation-and-delivery tool. It takes arbitrary prompts, generates images through fal.ai's xAI Grok Imagine model, and then sends them to specified messaging channels via OpenClaw. It also invokes the openclaw CLI through child_process or calls a local gateway HTTP API, which are materially relevant capabilities absent from the description. While use of FAL_KEY is consistent with the declaration, the overall primary purpose and accessed resources are broader than stated.
The description says the skill generates a Clawdy selfie with an installed local helper script and configured FAL_KEY. The supplied code instead is a shell script explicitly for generating a Clawdy selfie VIDEO, not a still image. It relies on SEEDANCE_API_KEY and the Seedance API endpoint, not FAL_KEY. It also uploads the local reference image to public hosting providers to obtain a URL, polls a remote task API, downloads the produced video, and sends the file to a user-specified OpenClaw channel. These are material behavior differences and undeclared external/resource-access capabilities, so the description does not accurately represent the code.
The script has shell execution capability and performs sensitive actions including outbound network requests, local file writes, and channel messaging, but the stated metadata only describes selfie generation. This mismatch increases the risk that a caller grants or invokes broader capabilities than expected, reducing transparency and consent around what the skill can actually do.
The script reads sensitive environment variables such as FAL_KEY and OPENCLAW_GATEWAY_TOKEN and performs outbound network requests, but these capabilities are not declared in the skill permissions/manifest. Undeclared env and network access weakens user review and consent, making secret use and data egress less transparent than the skill description suggests.
The script reads sensitive environment variables such as FAL_KEY and OPENCLAW_GATEWAY_TOKEN and performs outbound network requests, but these capabilities are not declared in the skill permissions/manifest. Undeclared env and network access weakens user review and consent, making secret use and data egress less transparent than the skill description suggests.
The script behavior materially differs from the skill description: it generates and sends a video, not a selfie image. This mismatch can mislead users and reviewers about what data is processed and transmitted, reducing informed consent and making other risky behaviors harder to detect.
The manifest says the skill uses a local helper script and FAL_KEY, but this script instead uses a different remote API endpoint and different credentials. That discrepancy hides external data flows and secret usage from users and operators, increasing the risk of unauthorized disclosure and trust bypass.
These strings impose a fixed gendered output without any user choice or documented justification. That is a natural-language policy concern because the skill forces a specific identity characteristic rather than offering opt-in or context for the restriction.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
--arg output_format "$OUTPUT_FORMAT" \
'{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: $output_format}')
RESPONSE=$(curl -fsSL -X POST "https://fal.run/xai/grok-imagine-image/edit" \
-H "Authorization: Key $FAL_KEY" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD")
The skill description says it generates a selfie, but the script also automatically sends the generated file to an OpenClaw channel. That is a semantic mismatch that can cause unintended data disclosure because users may expect local generation only, not transmission into a chat or collaboration channel.
Channel messaging is an additional capability beyond image generation and is not obviously necessary for the stated purpose. Because the script accepts a channel argument and sends content there automatically, it can be used to exfiltrate generated content or spam channels in ways not justified by the advertised functionality.
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.
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.
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 code does not use a local helper script as described; instead it directly contacts fal.ai and optionally an OpenClaw gateway. This mismatch reduces transparency and can mislead reviewers about trust boundaries, causing user prompts, generated media, and secrets to be exposed to remote services unexpectedly.
The code performs an external POST to fal.run containing the prompt and authenticates with FAL_KEY. External transmission is expected for a cloud image-generation service, but in this skill it is more dangerous because the manifest/description understate remote processing, so users may not understand that their inputs and service usage metadata leave the local environment.
}
// Fallback to fetch
const response = await fetch("https://fal.run/xai/grok-imagine-image", {
method: "POST",
headers: {
Authorization: `Key ${falKey}`,
The script transmits the user's prompt to fal.ai and then sends the generated image URL/media to OpenClaw or a gateway, but the skill description does not clearly warn about this external sharing. In this context, prompts may contain sensitive or identifying content, and generated media publication to messaging channels can create privacy and confidentiality issues.
The implementation sends generated content to external messaging channels, which goes beyond the stated 'generate a selfie' scope. Scope drift is dangerous because users may authorize a seemingly local/limited image-generation skill without realizing it can publish content externally to channels or users.
The function builds a shell command with untrusted values for channel, message, and media using string interpolation and executes it with child_process.exec. This creates a command injection risk: crafted input containing shell metacharacters or quotes could execute arbitrary commands on the host running the skill.
The script hardcodes a default external base URL to a remote API domain, establishing undeclared outbound connectivity by default. In the context of a skill described as local and tied to a different credential, this materially increases the danger because remote transmission happens unless operators override it.
# --- Config ---
SEEDANCE_API_KEY="${SEEDANCE_API_KEY:-}"
SEEDANCE_BASE_URL="${SEEDANCE_BASE_URL:-https://api.outai.top/api}"
REFERENCE_PUBLIC_URL="${CLAWDY_REFERENCE_URL:-}"
CREATE_RETRIES="${SEEDANCE_CREATE_RETRIES:-3}"
POLL_INTERVAL="${SEEDANCE_POLL_INTERVAL:-60}"
The script uploads a local reference image to public third-party hosting services to obtain a URL. This exposes local asset content outside the declared system boundary and creates unnecessary disclosure, persistence, and reuse risk on unrelated external infrastructure.
The reference image is sent to file.io and 0x0.st without any explicit warning in the script usage or manifest. Users may reasonably assume the asset stays local or within the named provider, so the undisclosed public upload undermines consent and privacy expectations.
This POST sends user prompt content and an image reference to an external service using an API key. External transmission is expected for a media-generation workflow, but in this skill it is insufficiently disclosed and routed to a service not described by the manifest, making the network exfiltration risk real.
local image_url="$2"
local video_prompt="$3"
curl -fsSL -X POST "${SEEDANCE_BASE_URL}/v1/video/seedance-2" \
-H "Authorization: Bearer $SEEDANCE_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n \
The prompt text and reference image URL are transmitted to an external video-generation API, but the usage text does not disclose that user content leaves the local environment. In a skill advertised as using a local helper, this omission is especially misleading and increases privacy and policy risk.
Detected: suspicious.env_credential_access