Back to skill

Security audit

Fal Ai

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but users should review it because it stores API keys and full request media in local workspace files while sending prompts and media to fal.ai.

Install only if you are comfortable sending prompts, images, and videos to fal.ai. Prefer FAL_KEY in a protected environment variable instead of TOOLS.md, avoid submitting confidential media, and regularly inspect or delete ~/.openclaw/workspace/fal-pending.json because it may retain full request contents.

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
scripts/fal_client.py:136
Finding

Plaintext fal.ai API Credential Storage in Workspace Documentation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fal_client.py:204
Finding

Persistent Storage of Complete Prompts and Base64-Encoded Private Media

Content
View full analysis
str: """Convert local file (image or video) to base64 data URI""" import base64 import mimetypes mime_type, _ = mimetypes.guess_type(file_path) if not mime_type: # Default based on extension ext = Path(file_path).suffix.lower() mime_map = { '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.webp': 'image/webp', '.gif': 'image/gif', '.mp4': 'video/mp4', '.mov': 'video/quicktime', '.webm': 'video/webm', '.avi': 'video/x-msvideo', '.mkv': 'video/x-matroska' } mime_type = mime_map.get(ext, 'application/octet-stream') file_size = os.path.getsize(file_path) file_size_mb = file_size / (1024 * 1024) # Warn for large files if file_size_mb > 50: print(f"WARNING: File is {file_size_mb:.1f}MB. Large files may be slow or fail.", file=sys. ...[truncated 2851 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (14)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/fal_client.py (reported line 124)May include surrounding context.

python
}

def get_api_key():
    """Get API key from env, openclaw.json, or TOOLS.md"""
    # 1. Environment variable (highest priority)
    key = os.environ.get("FAL_KEY")
    if key:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes capabilities involving environment access, file read/write, shell, and network use, but does not declare any explicit tool scope or permission boundaries. This increases the chance of over-privileged execution and makes it harder for a calling agent or reviewer to understand what the skill is allowed to access, especially since it handles API keys, local files, and outbound requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description uses broad invocation language such as 'use when asked to generate images' and 'anything involving fal.ai,' which can cause the skill to trigger in situations that only loosely match the user's request. Over-broad routing increases the risk of unnecessary external API use, unintended data transmission, or execution of file/network operations when a simpler or local response would have been safer.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation instructs users to submit images and videos to fal.ai, including local files converted to data URIs, but does not clearly warn that this sends potentially sensitive media to a third-party service. In context, this skill is specifically built to process user-provided media, so omission of an external-sharing warning materially increases privacy and confidentiality risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 210)May include surrounding context.

md
## Adding New Models

1. Find the model on fal.ai and check its `/api` page
2. Add entry to `references/models.json` with input/output schema
3. Test with a simple request

**Note:** Queue URLs use base model path (e.g., `fal-ai/flux` not `fal-ai/flux/dev/image-to-image`). The script handles this automatically.

Tainted flow: 'PENDING_FILE' from os.environ.get (line 61, credential/environment) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
88% confidence
Finding

The output path for pending request state is derived from the FAL_PENDING_FILE environment variable and then written without validation. If an attacker can influence the environment in which this skill runs, they can redirect writes to arbitrary filesystem locations writable by the process, causing file clobbering or persistence in unexpected paths.

Content

Scanner excerpt · scripts/fal_client.py (reported line 182)May include surrounding context.

python
def save_pending(data):
    """Save pending requests to file"""
    PENDING_FILE.parent.mkdir(parents=True, exist_ok=True)
    PENDING_FILE.write_text(json.dumps(data, indent=2))

def submit(model_id: str, input_data: dict, skip_validation: bool = False) -> dict:
    """Submit a request to the queue with validation"""

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/fal_client.py (reported line 184)May include surrounding context.

python
PENDING_FILE.parent.mkdir(parents=True, exist_ok=True)
    PENDING_FILE.write_text(json.dumps(data, indent=2))

def submit(model_id: str, input_data: dict, skip_validation: bool = False) -> dict:
    """Submit a request to the queue with validation"""
    
    # Validate input

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · scripts/fal_client.py (reported line 188)May include surrounding context.

python
PENDING_FILE.parent.mkdir(parents=True, exist_ok=True)
    PENDING_FILE.write_text(json.dumps(data, indent=2))

def submit(model_id: str, input_data: dict, skip_validation: bool = False) -> dict:
    """Submit a request to the queue with validation"""
    
    # Validate input

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This client can transform arbitrary local files into data URIs and submit them to the fal.ai service, enabling exfiltration of local file contents if higher-level tooling passes attacker-influenced paths. In a skill context, outbound transmission of local content to a third-party API is especially sensitive because users may not realize local files are being embedded and sent off-host.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a client for generating images and media through the fal.ai API with queue polling. Spawning a local binary via subprocess.run adds host-execution capability beyond straightforward API interaction, and that capability is not mentioned in the skill description.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/fal_client.py (reported line 330)May include surrounding context.

python
# Try to get video info with ffprobe
    try:
        result = subprocess.run(
            ['ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_streams', file_path],
            capture_output=True, text=True
        )

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The entry keyed as "fal-ai/nano-banana-pro" is labeled in natural language as "Gemini 3 Pro Image," and the edit variant repeats that naming mismatch. While not a security flaw by itself, this is a user-facing natural-language inconsistency that could mislead users about which model/provider is being used.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The client reads API credentials from unrelated local files, including TOOLS.md, instead of limiting secret intake to a dedicated secret source such as environment variables or a secure config store. This broadens the skill’s access to local sensitive data and can unintentionally harvest or misuse credentials present elsewhere in the workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

Scanning TOOLS.md for an API key accesses local file content that may contain credentials or unrelated secrets, without a clear user-facing warning. While the immediate use is to find the fal.ai key, this pattern normalizes secret scraping from free-form documents and increases the chance of unintended credential exposure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.