Back to skill

Security audit

Creatok Generate Video

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its CreatOK video-generation purpose, but it has a real artifact-path bug that can write result files outside its documented folder.

Review before installing. Use this only if you trust CreatOK with your prompts, reference images, generated-video metadata, and CREATOK_API_KEY. Until the run_id path issue is patched, only use simple run IDs without slashes, backslashes, dots, or path separators, and avoid exposing the CLI arguments to untrusted input.

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

T09 · Insecure Skill Coding Practices

Warning
Location
lib/artifacts.js:15
Finding

Path Traversal Through User-Controlled Run ID Allows Writes Outside the Artifact Directory

Content
View full analysis
s.trim()); if (key === '--model') args.model = value; if (key === '--run_id') args.runId = value; if (key === '--timeout_sec') args.timeoutSec = Number(value); if (key === '--poll_interval') args.pollInterval = Number(value); ``` The untrusted value is passed into artifact storage: ```js // lib/generate-video.js:181-198 async function runGenerateVideoStatus({ taskId, runId, skillDir, model = null, wait = false, pollInterval = 3, timeoutSec = 600, client = defaultClient(), }) { const artifacts = artifactsForRun(skillDir, runId); artifacts.ensure(); const raw = wait ? await pollGenerate(client, String(taskId), pollInterval, timeoutSec) : await client.getTaskStatus(String(taskId)); ``` The artifact root is constructed without validating the run ID or checking that the resulting path remains beneath `.artifacts`: ```js // lib/artifacts.js:30-35 function artifactsRootForSkill(skillDir) { return path.join(skillDir, '.artifacts'); } function artifactsForRun(skillDir, runId) { return new Artifacts(path.join(artifactsRootForSkill(skillDir), runId)); } ``` The resulting path is subsequently used for recursive directory creation and file writes: ```js // lib/artifacts.js:8-26 ensure() { for (const name of ['input', 'transcript', 'vision', 'outputs', 'logs']) { fs.mkdirSync(path.join(this.root, name), { recursive: true }); } } writeJson(relPa ...[truncated 3311 chars]
Remediation
View remediation
/.artifacts`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description is domain-specific to TikTok video/ad generation or review, but this code chunk does not implement any TikTok, video, ad, resume, or checking functionality. Instead, it provides generic filesystem helpers for creating artifact folders and saving files for skill runs. While such utilities could support a larger workflow, this chunk’s actual purpose is artifact persistence and directory management, which is materially different from the declared end-user purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description suggests end-user functionality related to TikTok video, ad, or sales-video generation and status checking. However, the supplied code does not generate, resume, inspect, or manage TikTok content. Its actual purpose is infrastructure-level: querying a CreatOK service for available skill capabilities using an authenticated HTTP GET request. This is a materially different primary behavior from the declared purpose, so the description does not accurately represent the code chunk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares runtime capabilities that imply network and environment-variable access but does not explicitly scope or constrain tool permissions. That increases the chance an agent runtime grants broader-than-necessary access, making misuse of the API key or unintended outbound requests harder to audit and contain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Overly broad trigger phrases can cause the skill to activate in normal conversation when the user did not intend to invoke an external API-backed workflow. In this skill, accidental activation matters because it can lead to confirmation prompts around paid generation, data being sent to a third-party service, or recovery logic engaging unexpectedly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Ambiguous recovery/checking triggers like checking a task ID can match unrelated contexts and may cause the agent to query task status using identifiers mentioned in conversation. Because recovery mode can continue existing jobs and expose task state or URLs, weakly scoped triggers increase the risk of unintended data disclosure or unnecessary external requests.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
## Existing Task Recovery

- If the user already has a `task_id`, this skill should continue from that task instead of starting a new one.
- In recovery mode, do not ask the user to restate the prompt or creative brief if the task id is already available.
- The model can either:
  - check the current task status once
  - or continue waiting and polling if the user wants to keep checking

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code performs a network call and sends a bearer token from configuration in the Authorization header. There is no confirmation prompt, logging, comment, or docstring in this file disclosing that credentials are transmitted to an external endpoint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code reads a local file and transmits its contents to a remote upload endpoint via a presigned URL. Within this file, there is no confirmation prompt, logging/print disclosure, or comment/docstring warning that local image data will be sent off-system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code uploads each reference image file via client.uploadImageFile, which sends user-provided local files to a remote service. In this file there is no confirmation prompt, warning comment/docstring, or other user-facing disclosure around that data transfer, so users may not realize their images leave the local system.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The client.submitTask call sends the prompt and generation settings to an external backend, which can include user-authored content and metadata. This file does not include any confirmation, warning text, or explanatory comment indicating that this information is transmitted off-system.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The handoff rule uses broad natural-language examples like 'go ahead and generate' or 'turn this into a video' without requiring a strong confirmation boundary or explicit disambiguation. In a multi-skill agent, this can cause unintended routing into a later skill with carried-forward context, leading to actions being taken under the wrong skill or with incomplete user intent validation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code performs a remote capability request via effectiveClient.getCapabilities(timeoutSec) but includes no confirmation prompt, logging, print statement, or explanatory comment/docstring describing the network action. For a code file, outbound calls that may transmit user or system data should have some visible disclosure unless the warning is documented elsewhere.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.