T03 · Remote Payload Retrieval and Execution
- Location
SKILL.md:53- Finding
Remote installer is executed without integrity verification
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent content-generation skill, but it needs review because it can use social-media session cookies, automate Reddit/X activity, fetch arbitrary URLs, and lacks strong containment around paths and browser execution.
Install only if you are comfortable with a skill that can browse external pages, send prompts/specs to Exa and fal.ai, and optionally use Reddit/X cookies to act through your accounts. Use dedicated low-privilege API keys, avoid internal or sensitive URLs, do not provide browser cookies unless you need publishing/tracking, and run it in a sandboxed environment until URL, path, dependency, and browser-sandbox hardening are added.
SKILL.md:53Remote installer is executed without integrity verification
scripts/extractors/extract.py:17Unvalidated source URLs permit server-side request forgery and local resource access
scripts/extractors/extract.py:21Chromium processes untrusted web content with the browser sandbox disabled
scripts/discover_topics.py:42Caller-controlled filesystem paths are not constrained to the declared project directory
scripts/extractors/extract.py:88Downloaded PDF files are left behind in the system temporary directory
pyproject.toml:6Floating dependency constraints permit unreviewed future package versions
The declared description presents a content generation skill that converts input materials such as URLs, papers, podcasts, Reddit threads, or GitHub repos into publishable content assets. The supplied code does something materially different: it autonomously discovers trending topics relevant to a brand by querying Exa and scraping Reddit/X, then ranks them for relevance. This is not just a supporting component of generation; it is a separate primary capability focused on research and trend discovery. The code also accesses external web platforms through Playwright and can load cookie files for Reddit/X sessions, which are significant undeclared behaviors. While EXA_API_KEY is mentioned in the description, FAL_KEY is not used here, and no content generation or transformation logic appears in this chunk. Therefore the description does not accurately represent the actual behavior.
The declared description presents this skill as an automated content generation system whose primary function is transforming source material into finished content artifacts. The supplied code instead implements only a source extraction utility: it routes URLs by type, fetches/render pages, extracts readable text or README/PR/PDF text, and returns structured JSON. While extraction could be a supporting component in a broader content-generation pipeline, this chunk’s actual primary purpose is materially different from the declared purpose. The description also mentions image generation, topic discovery, recipes, and brand graphs, none of which appear in the code.
The description presents a full content-generation pipeline capable of turning many kinds of source material into multiple content formats, including text outputs and image outputs. The supplied code chunk only implements one supporting subcomponent: image generation via fal.ai from an already prepared spec or prompt. It uses FAL_KEY, but there is no evidence of source-material ingestion, topic discovery, recipe/brand-graph orchestration, or generation of non-image content. This is a material scope mismatch in primary purpose and supported capabilities, even though infographics/diagrams are partially aligned.
The declared description emphasizes automated content generation from inputs like papers, podcasts, Reddit threads, and GitHub repos, with recipes/brand graphs and dependencies on FAL_KEY and EXA_API_KEY. The supplied code does not generate or transform source material at all. Its primary purpose is materially different: publishing existing content from a local directory to Reddit or X/Twitter via Playwright using authenticated session cookies, while modifying links with UTM tags and recording publication metadata. These are significant undeclared capabilities and a different workflow, so this is a clear description-behavior mismatch.
The declared description presents this skill as an automated content generation engine for creating posts and media from source material. The supplied code chunk does not generate content at all. Its primary function is post-publication analytics: it scrapes Reddit and X engagement metrics, processes publish records, and writes feedback data. That is a materially different purpose from content creation. The code also accesses external social platforms through Playwright and optional cookie files, which is not reflected in the declared description. While the broader product wording mentions brand graphs, this script specifically implements engagement tracking and feedback updates, not content generation, so the description does not accurately represent the actual behavior.
This is a clear description-behavior mismatch. The description promises a content generation pipeline that converts source material into platform-ready content and references brand graphs, recipes, and image/topic APIs. The actual code chunk contains only tests for an extractor script: it invokes a subprocess, classifies URLs by type, validates extracted text/title/word count, and checks truncation and error JSON behavior. While source extraction could be a supporting component of a larger content-generation system, this specific code chunk does not perform generation or anything close to the declared primary purpose. Therefore the declared description does not accurately represent what this code actually does.
The declared description presents a runtime content-generation skill, but the supplied code only contains unit tests for validating YAML recipe metadata and file references. It does not generate posts, summaries, diagrams, or any platform-ready content, nor does it ingest external source material or call external services/APIs. While the test code references concepts like recipes and brand_graph, that is only schema validation support and not the declared primary capability. This is a clear description-behavior mismatch.
The trigger language is extremely broad and can match generic requests like 'make a post from this' or 'turn this into content,' causing the skill to activate in contexts where users did not intend scraping, external API use, or credential-backed actions. Over-broad activation increases the chance of unnecessary data processing, unexpected tool invocation, and user surprise around external side effects.
This task explicitly plans for the skill to write or define its own SKILL.md, which is a self-modification capability affecting the agent's instruction set. In agent systems, allowing a skill to author or rewrite the instructions that govern future behavior can enable persistence, privilege escalation, safety bypasses, or insertion of adversarial directives, especially because SKILL.md is described here as 'the instruction set that makes the OpenClaw agent a content engine.'
- **Effort:** S
- **Blocked by:** Recipe YAML schema.
### Write SKILL.md (core skill definition)
- **What:** Write the OpenClaw SKILL.md that teaches the agent the full Content Claw pipeline: recipe execution, brand graph wizard, recipe listing, error handling, all user commands.
- **Why:** This IS the product. The SKILL.md is the instruction set that makes the OpenClaw agent a content engine.
- **Effort:** M
The script reads secrets from a local .env file and uses them to access external services, which is a real sensitive capability. If the skill manifest does not explicitly declare environment/secret access, users and hosting systems may not understand that the skill consumes credentials, creating a permission transparency and least-privilege issue.
This extractor performs broad outbound network access to arbitrary user-supplied URLs via Playwright and httpx, but the finding indicates that capability is not declared in the skill's permissions. Undeclared network access is dangerous because it enables fetching untrusted remote content, increases SSRF-style exposure to internal services or cloud metadata endpoints if reachable, and reduces transparency for users and hosting platforms about what the skill can contact.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
uv run generate_image.py --prompt "description" <output-path>
Environment:
FAL_KEY - Required. Set in .env file.
"""
import json
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
f"\n\n{content_description}"
)
return prompt
FAL_MODELS = {
The skill metadata frames this tool as a content-generation engine, but this file automates authenticated social-media drafting workflows for Reddit and X. That scope expansion is dangerous because it enables actions on external user accounts using stored session cookies, which materially changes the trust boundary from local content processing to account-affecting browser automation.
The code loads authenticated Reddit cookies from disk and injects them into a Playwright browser context, allowing the script to operate as the user on a third-party platform. In a skill advertised for content generation, this is an unjustified credentialed action surface that could be abused for account misuse, unintended posting, or session theft exposure if cookie files are mishandled.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env():
"""Load only declared keys from .env (scoped to FAL_KEY, EXA_API_KEY)."""
allowed = {"FAL_KEY", "EXA_API_KEY"}
env_path = Path(__file__).parent.parent / ".env"
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env():
"""Load only declared keys from .env (scoped to FAL_KEY, EXA_API_KEY)."""
allowed = {"FAL_KEY", "EXA_API_KEY"}
env_path = Path(__file__).parent.parent / ".env"
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env():
"""Load only declared keys from .env (scoped to FAL_KEY, EXA_API_KEY)."""
allowed = {"FAL_KEY", "EXA_API_KEY"}
env_path = Path(__file__).parent.parent / ".env"
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def load_env():
"""Load only declared keys from .env (scoped to FAL_KEY, EXA_API_KEY)."""
allowed = {"FAL_KEY", "EXA_API_KEY"}
env_path = Path(__file__).parent.parent / ".env"
if not env_path.exists():
return
for line in env_path.read_text().splitlines():
No suspicious patterns detected.