Back to skill

Security audit

OpenStoryline Use

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an OpenStoryline editing workflow, but its Feishu helper can upload any readable local file using local Feishu credentials without strong scoping or confirmation.

Review this skill before installing if you plan to use Feishu delivery. Only run the sender on generated video files you have checked, confirm the recipient, and avoid giving the agent arbitrary file paths or broad access to sensitive project directories. The core local OpenStoryline workflow is disclosed, but the file-sending helper needs tighter limits to be low-risk.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/feishu_file_sender.py:116
Finding

Unrestricted Local File Upload to Feishu

Content
View full analysis

Vulnerability Details

File Location: scripts/feishu_file_sender.py, lines 116–133 and 195–224
Vulnerability Type: Arbitrary local file disclosure through insufficient path validation
Risk Level: Medium

Vulnerable Code

python
def upload_file(token: str, file_path: Path, file_type: str) -> str:
    headers = {"Authorization": f"Bearer {token}"}
    with file_path.open("rb") as f:
        files = {"file": (file_path.name, f)}
        data = {
            "file_type": file_type,
            "file_name": file_path.name,
        }
        resp = requests.post(
            FEISHU_UPLOAD_URL,
            headers=headers,
            data=data,
            files=files,
            timeout=30,
        )
    resp.raise_for_status()
    data = resp.json()
    if data.get("code") != 0:
        raise RuntimeError(f"Upload failed: {data}")
    return data["data"]["file_key"]
python
def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Upload file to Feishu and send")
    parser.add_argument("--file", required=True, help="Local file path")
    parser.add_argument("--receive-id", default=None, help="chat_id or open_id")
    parser.add_argument(
        "--receive-id-type",
        default=None,
        help="chat_id / open_id / user_id (auto-detect if omitted)",
    )
    parser.add_argument(
        "--file-type",
        default="stream",
        help="file_type for upload, default stream",
    )
    return parser.parse_args()


def main() -> None:
    args = parse_args()
    file_path = Path(args.file)
    if not file_path.exists():
        raise FileNotFoundError(f"File not found: {file_path}")

    config = load_openclaw_config()
    app_id, app_secret = resolve_feishu_account(config)

    receive_id = resolve_receive_id(args.receive_id)
    receive_id_type = infer_receive_id_type(receive_id, args.receive
...[truncated 2755 chars]
Remediation
View remediation

Remediation Suggestions

  1. Resolve the requested path using Path.resolve(strict=True) before opening it.
  2. Restrict uploads to approved OpenStoryline output roots, such as the current session's render directory.
  3. Use Path.relative_to() against a trusted canonical output root and reject paths outside that root.
  4. Require Path.is_file() and reject symbolic links or resolve them before containment validation.
  5. Allow only expected video extensions such as .mp4, and validate the actual media format rather than relying solely on the filename.
  6. Associate the file with the active session_id and require it to match a generated output_*.mp4 artifact.
  7. Display the canonical file path, size, and Feishu recipient and require explicit user confirmation before upload.
  8. Validate receive_id_type against a fixed allowlist and ensure the recipient matches the active conversation where possible.
  9. Avoid logging access tokens, application secrets, or complete API responses that could contain sensitive metadata.

T08 · Insecure Dependencies

Note
Location
SKILL.md:298
Finding

Unpinned Runtime Installation of a Third-Party Dependency

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 298–302
Vulnerability Type: Unpinned dependency installation
Risk Level: Low

Vulnerable Code

bash
python3 -m pip install requests

Technical Analysis

The skill documentation instructs the agent to install requests without specifying a reviewed version, integrity hash, lockfile, or trusted package index. Dependency resolution therefore occurs at execution time and may install a different release as the package index changes.

Although requests is a well-known package and no evidence of typosquatting or an intentionally malicious dependency was found, the instruction provides weaker supply-chain reproducibility and integrity than a pinned dependency declaration. It may also introduce an incompatible future version into the active environment.

Attack Path

  1. The agent follows the documented setup instruction.
  2. pip contacts the package index configured in the user's environment.
  3. The resolver selects whichever requests release currently satisfies the unbounded requirement.
  4. A compromised package-index response, compromised release, unsafe configured mirror, or incompatible future release is downloaded and installed.
  5. The installed package executes Python code when imported or during package installation, within the privileges of the invoking account.
  6. feishu_file_sender.py imports and uses that package for credential-bearing network requests.

Exploitation depends on compromise or manipulation of the configured dependency source or package release; the audited project itself does not retrieve a custom malicious package.

Impact Assessment

A compromised dependency could execute code with the permissions of the Python environment's user, access files available to that account, intercept Feishu credentials and uploaded content, or alter network destinations. An incompatible release could instead cause availabilit ...[truncated 275 chars]

Remediation
View remediation

Remediation Suggestions

  1. Declare the dependency in a reviewed requirements or lock file.
  2. Pin an explicitly tested version, for example with an exact requests==X.Y.Z constraint.
  3. Use package hashes through pip --require-hashes where practical.
  4. Install only from an explicitly trusted package index.
  5. Prefer an isolated virtual environment rather than modifying a shared Python environment.
  6. Periodically update the pinned version after vulnerability review and compatibility testing.
  7. Document the expected dependency version alongside the supported Python versions.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The manifest frames this as a local OpenStoryline usage skill, but the body introduces unrelated external file-transfer behavior via Feishu, including reading local credentials and sending rendered videos to external recipients. This mismatch is dangerous because users may authorize a local editing workflow without realizing the skill can exfiltrate files and use separate third-party messaging APIs.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

These instructions add the capability to read Feishu credentials from local OpenClaw configuration and send files to external chat/user recipients. Accessing local credentials and using them to transmit files off-host materially increases the risk of secret misuse, unauthorized messaging, and exfiltration of private video content.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script provides Feishu file upload and messaging capabilities that are unrelated to the stated OpenStoryline purpose of starting local services and editing video sessions. In a skill package, unrelated outbound transfer functionality is dangerous because it can be used to move arbitrary local files off-host under the guise of a benign media-editing tool.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code obtains Feishu credentials, uploads a local file, and sends a message containing that file to an external service. Because the skill context is OpenStoryline local session/editing, this external messaging capability materially increases exfiltration risk and is not justified by the declared purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill requests capabilities implied by its instructions—environment access, file reads, MCP/process control, and network use—but does not declare any explicit tool scope or allowlist. That makes review and enforcement harder and increases the chance the agent can invoke more powerful operations than users expect, especially because the document includes process launching, config editing, and network interactions.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

bash
# minimax
cd <repo-root> && source .venv/bin/activate && python scripts/update_config.py --config ./config.toml --set generate_voiceover.providers.minimax.base_url=https://api.minimax.chat/v1/t2a_v2
cd <repo-root> && source .venv/bin/activate && python scripts/update_config.py --config ./config.toml --set generate_voiceover.providers.minimax.api_key=REPLACE_WITH_MINIMAX_KEY

# bytedance

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The markdown states that the lang parameter currently only supports zh / en, which imposes a language/locale constraint in the skill's operating instructions. The file does not present this as a user choice with fallback handling for other languages, nor does it justify the restriction as region-specific compliance.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation instructs the agent to send rendered videos to Feishu, which extends beyond the stated local OpenStoryline workflow. That creates a data-transfer path for potentially sensitive user media to leave the local machine or trusted local service boundary without being part of the advertised scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code creates a remote session and sends the user's prompt to an external service via HTTP and WebSocket, but the script provides no confirmation prompt or user-facing warning that input text will be transmitted off-process. For a code file, network transmission of user data should have some visible disclosure unless the warning exists elsewhere, and no such disclosure is present in this file.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/feishu_file_sender.py (reported line 102)May include surrounding context.

python
def get_tenant_access_token(app_id: str, app_secret: str) -> str:
    resp = requests.post(
        FEISHU_TOKEN_URL,
        json={"app_id": app_id, "app_secret": app_secret},
        timeout=15,

Tainted flow: 'data' from requests.post (line 160, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/feishu_file_sender.py (reported line 122)May include surrounding context.

python
"file_type": file_type,
            "file_name": file_path.name,
        }
        resp = requests.post(
            FEISHU_UPLOAD_URL,
            headers=headers,
            data=data,

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This request sends a file message to an external Feishu recipient, completing an outbound data-transfer path from local disk to a remote chat or user. In the context of a skill that is supposed to operate on local OpenStoryline sessions, this materially increases the chance of covert or accidental exfiltration.

Content

Scanner excerpt · scripts/feishu_file_sender.py (reported line 152)May include surrounding context.

python
"msg_type": "file",
        "content": json.dumps({"file_key": file_key}),
    }
    resp = requests.post(
        FEISHU_SEND_MSG_URL,
        headers=headers,
        params=params,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script uploads the specified local file and sends it via Feishu immediately, with no user-facing warning, dry run, or confirmation step. In an agent skill context, silent transmission of local content is dangerous because it can surprise users and facilitate accidental or unauthorized disclosure of sensitive project files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The CLI constrains language override choices to only "zh" and "en", which hard-codes a narrow locale policy in natural-language-facing behavior. The file does not document a justified regional constraint or offer broader locale choice, so this may conflict with language/locale policy requirements.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script reads appId/appSecret from the user's OpenClaw configuration and uses them in an HTTP request to obtain an access token, but there is no comment, prompt, or user-facing notice that locally stored service credentials will be accessed and used. This matches the missing-warning criterion for access to sensitive credentials in code files.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.