Back to skill

Security audit

subtitle-refiner

Security checks for vulnerabilities and agentic risk

Overview

This subtitle tool does what it advertises, but it exposes API credentials and subtitle contents through verbose logs and automatic third-party delivery.

Review before installing. Do not use this skill with confidential subtitles unless you accept sending content to SiliconFlow and Feishu. Do not paste real API keys into chat. The publisher should remove raw token and payload logging, add an explicit confirmation before external processing and Feishu delivery, and document the exact data sent externally.

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

Error
Location
scripts/refine.py:251
Finding
API Credential and Private Subtitle Content Are Written to Process Logs## Vulnerability Details **File Location**: `scripts/refine.py`, lines 251-270 **Vulnerability Type**: Sensitive information exposure through verbose logging **Risk Level**: High ### Vulnerable Code ```python print(f"🔑 认证: Bearer {SILICONFLOW_API_KEY}", file=sys.stderr) print(f"⏱️ 超时: 连接=10秒, 读取=300秒", file=sys.stderr) # 打印消息内容(完整不截断) print(f"\n💬 消息数量: {len(messages)}", file=sys.stderr) for i, msg in enumerate(messages, 1): role = msg.get("role", "unknown") content = msg.get("content", "") print(f"\n{'=' * 80}", file=sys.stderr) print(f" 消息 {i} [{role}]:", file=sys.stderr) print(f"{'=' * 80}", file=sys.stderr) print(f"{content}", file=sys.stderr) print(f"{'=' * 80}", file=sys.stderr) # 打印完整的 payload(格式化的 JSON,完整内容) print(f"\n📦 完整请求体(JSON):", file=sys.stderr) print(f"{'=' * 80}", file=sys.stderr) print("```json", file=sys.stderr) print(json.dumps(payload, indent=2, ensure_ascii=False), file=sys.stderr) print("```", file=sys.stderr) print(f"{'=' * 80}\n", file=sys.stderr) ``` ### Technical Analysis The API request function writes the complete `SILICONFLOW_API_KEY` bearer credential to standard error. It also logs every complete prompt and the complete request payload without truncation or redaction. The prompts contain user-supplied subtitle content. Topic detection transmits and logs the first 20 subtitle entries, while subsequent refinement requests collectively process and log the rest of the subtitle document. Consequently, both an authentication secret and potentially confidential media transcripts can enter terminal history, OpenClaw logs, process-supervisor logs, CI output, centralized telemetry, or other diagnostic storage. Logging the credential is not required to perform API authentication, token accounting, subtitle refinement, or error diagnosis. It exceeds the minimum information necessary for the declared functionality. ### Attack Path 1. A user c ...[truncated 1298 chars]
Remediation
## Remediation Suggestions 1. Remove all logging of the `Authorization` header and `SILICONFLOW_API_KEY`. 2. If authentication status must be logged, use a constant redacted value such as `Bearer [REDACTED]`. 3. Do not log complete prompts, message arrays, payloads, API responses, or subtitle text by default. 4. Restrict normal diagnostics to non-sensitive metadata such as the endpoint hostname, model name, request identifier, content length, status code, and token counts. 5. If content-level debugging is required, place it behind an explicit opt-in debug setting, display a privacy warning, redact sensitive fields, and limit retained text. 6. Configure logs with restrictive permissions, short retention periods, and controls preventing transmission to untrusted telemetry systems. 7. Rotate any API key that may already have appeared in logs and delete affected logs where operationally possible. 8. Add automated tests that capture standard output and standard error and verify that neither the API key nor representative subtitle text appears.

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:29
Finding
Installation Documentation Encourages Users to Paste API Credentials into Agent Chat## Vulnerability Details **File Location**: `README.md`, lines 29-31 **Vulnerability Type**: Unsafe secret provisioning guidance **Risk Level**: Medium ### Vulnerable Documentation ```text Install the Skill from: https://gitee.com/real__cool/subtitle_refiner Configure the current shell environment variable: SILICONFLOW_API_KEY=sk-m****** Execute export SILICONFLOW_API_KEY=sk-m****** so the environment receives the API key. ``` The excerpt above is an English rendering of the installation instructions at the cited lines. Those instructions direct the user to send these commands, including the API credential, through the Agent chat window. ### Technical Analysis API keys should be provisioned through a dedicated secret manager, protected environment configuration, or a non-echoing local input mechanism. Asking users to provide the key through an Agent conversation unnecessarily places the secret in chat history and Agent context. Depending on the host environment, chat content may be retained in application databases, conversation exports, telemetry, debugging traces, model-provider requests, or other integrations. The Skill does not need the API key to appear in a user message; it only needs the value to be available in the process environment when the script runs. This guidance therefore expands credential exposure beyond the minimum privilege and data flow required by the declared subtitle-refinement functionality. ### Attack Path 1. A user follows the README installation instructions. 2. The user replaces the masked example with a valid API key and sends it in the Agent chat. 3. The chat platform, Agent runtime, telemetry system, or conversation-history store retains the message. 4. An unauthorized operator, compromised integration, other session participant, or attacker with access to exported history obtains the key. 5. The attacker submits unauthorized requests to SiliconFlow using the exposed credential. ...[truncated 466 chars]
Remediation
## Remediation Suggestions 1. Remove all instructions that ask users to paste API keys into an Agent conversation. 2. Direct users to OpenClaw's protected secret or environment configuration mechanism. 3. If no secret manager is available, provide local shell instructions that users execute themselves outside the chat session. 4. Prefer an interactive, non-echoing credential prompt or a protected configuration file with owner-only permissions. 5. Add an explicit warning that credentials must not be sent through chat, committed to source control, included in screenshots, or placed in shared shell-history files. 6. Use placeholder values only and clearly state that users must not send their real value back to the Agent. 7. Recommend revoking and rotating any key previously submitted through chat. 8. Document the minimum API permissions required and recommend a dedicated, limited-scope key where the provider supports one.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (24)

Tainted flow: 'SILICONFLOW_API_KEY' from os.environ.get (line 30, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
try:
        import requests
        # 发送一个简单的测试请求
        test_response = requests.get(
            "https://api.siliconflow.cn/v1/models",
            headers={"Authorization": f"Bearer {SILICONFLOW_API_KEY}"},
            timeout=10
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 222, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
print("```", file=sys.stderr)
        print(f"{'=' * 80}\n", file=sys.stderr)

        response = requests.post(
            API_ENDPOINT,
            headers=headers,
            json=payload,
Confidence
98% confidence
Finding
This code sends full subtitle content and authentication headers to a third-party API, and elsewhere in the same function it logs the full bearer token and request payload. In the context of subtitle processing, subtitles may contain sensitive or proprietary audio transcripts, so external transmission plus verbose logging materially increases confidentiality risk.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The function prints the full bearer token, all message contents, and the full JSON payload to stderr. This creates a direct leakage channel for credentials and sensitive subtitle content to logs, terminals, CI systems, or agent orchestration traces, which is especially dangerous in shared or hosted execution environments.

Ssd 3

High
Confidence
99% confidence
Finding
Verbose natural-language logging includes both full API credentials and user-supplied subtitle contents, which is a classic sensitive-data disclosure issue. In agent and cloud-run environments, stderr is often centrally collected, retained, and visible to operators, making accidental disclosure especially likely and harmful.

Missing User Warnings

High
Confidence
99% confidence
Finding
The raw API bearer token is printed to stderr, which can expose the credential to anyone with access to logs or execution traces. Credential disclosure can enable unauthorized API usage, billing abuse, and access to associated account capabilities.

Missing User Warnings

High
Confidence
98% confidence
Finding
The code both transmits full subtitle payloads to an external LLM service and echoes that same content to logs. If subtitles contain confidential meetings, customer data, or unpublished material, this results in unnecessary exposure to both a third party and any party with log access.

Context-Inappropriate Capability

High
Confidence
88% confidence
Finding
The skill includes capability to send files and messages to Feishu via an external CLI, which creates an outbound exfiltration path beyond the core subtitle-refinement function. In an agent skill context, especially with no metadata justifying such messaging, unsolicited transmission of generated or source content is dangerous because it can leak user data to a remote recipient.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill description explains that subtitles are processed by the GLM/SiliconFlow API but does not prominently warn that user subtitle content is sent to a third-party LLM service for analysis and refinement. This is a genuine privacy issue because users may assume local processing while sensitive transcript data is externally disclosed.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README states that optimized subtitles are automatically sent via Feishu, but it does not clearly warn users that subtitle contents may be transmitted to an external messaging platform. Subtitle files often contain sensitive business, personal, or meeting content, so silent or automatic forwarding creates a real privacy and data handling risk.

External Transmission

Medium
Category
Data Exfiltration
Content
| 配置项 | 值 |
|--------|-----|
| Endpoint | `https://api.siliconflow.cn/v1/chat/completions` |
| 模型 | `Pro/zai-org/GLM-4.7` |

如需更换模型,编辑 [`scripts/refine.py`](scripts/refine.py) 中的配置:
Confidence
88% confidence
Finding
The README documents use of an external API endpoint for subtitle processing, which confirms that user content leaves the local environment. In this skill context, the transmission is expected functionality rather than covert exfiltration, but it is still security-relevant because subtitle data may contain confidential information and the documentation does not adequately frame the privacy implications.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill description says optimized subtitles are sent through SiliconFlow and then delivered via Feishu, but it does not clearly warn users that subtitle content and chat identifiers will leave the local environment. This creates a real transparency and privacy issue because users may provide sensitive transcript content without informed consent about third-party transmission.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The workflow instructs the agent to directly run a script that processes the SRT file externally and automatically sends the result to Feishu, but it does not require an explicit warning or consent step first. In context, this is more dangerous because the trigger can occur automatically on file upload or keywords, increasing the chance of unintentional disclosure of subtitle content and chat metadata.

External Transmission

Medium
Category
Data Exfiltration
Content
### API 配置

- **Endpoint**: `https://api.siliconflow.cn/v1/chat/completions`
- **主模型**: `Pro/zai-org/GLM-4.7`
- **API Key**: 从环境变量 `SILICONFLOW_API_KEY` 读取
- **如果用户没有填写API Key,提示**:
Confidence
92% confidence
Finding
The skill explicitly sends subtitle content to an external API endpoint, which is a genuine external-transmission risk when handling potentially sensitive transcript data. In this context, the transmission is part of intended functionality, but it remains security-relevant because no clear minimization, consent, or retention disclosure is documented.

Intent-Code Divergence

Medium
Confidence
78% confidence
Finding
The module docstring explicitly promises '保持时间戳完全不变', implying a tightly constrained subtitle refinement operation. However, the code sends raw subtitle text to an LLM and writes back arbitrary returned text at L0715-L0716 and L0824-L0826 without validating line count, formatting, or subtitle block integrity, so the documented guarantee of invariant-preserving refinement is not actually enforced by code.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The natural-language strings and user-facing behavior are written entirely in Chinese, indicating the skill is effectively constrained to a single language. There is no opt-in, locale selection, or documented justification that this is a region-specific tool, which can violate language/locale policy expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
# =====================

SILICONFLOW_API_KEY = os.environ.get("SILICONFLOW_API_KEY", "").strip()
API_ENDPOINT = "https://api.siliconflow.cn/v1/chat/completions"
PRIMARY_MODEL = "Pro/zai-org/GLM-4.7"
FALLBACK_MODEL = "Qwen/Qwen2.5-7B-Instruct"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# =====================

SILICONFLOW_API_KEY = os.environ.get("SILICONFLOW_API_KEY", "").strip()
API_ENDPOINT = "https://api.siliconflow.cn/v1/chat/completions"
PRIMARY_MODEL = "Pro/zai-org/GLM-4.7"
FALLBACK_MODEL = "Qwen/Qwen2.5-7B-Instruct"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
print("```", file=sys.stderr)
        print(f"{'=' * 80}\n", file=sys.stderr)

        response = requests.post(
            API_ENDPOINT,
            headers=headers,
            json=payload,
Confidence
96% confidence
Finding
This outbound API call transmits user subtitle data to a remote service for processing. Because the skill also lacks strong disclosure boundaries and logs the same content locally, the external transmission meaningfully increases the chance of sensitive data exposure.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
]

    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
]

    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The refined subtitle file is sent to Feishu automatically as part of the workflow, creating a secondary outbound data channel. In an agent environment, automatic forwarding without explicit execution-time disclosure or confirmation can leak processed content to unintended recipients.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The skill documentation and example prompts are presented entirely in Chinese except for a few English trigger phrases, with no indication that users may choose another language. This can constitute a language/locale policy issue because the skill appears to impose a specific language without user opt-in or documented necessity.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
The skill description and operational guidance are presented only in Chinese, which may effectively force a specific language for use and interpretation. The file does not offer an alternative language, user opt-in, or a documented reason that the skill must be Chinese-only.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
The module docstring includes a Chinese-only description ('AI 驱动的字幕优化工具') without indicating that users can choose their preferred language or locale. The policy for this audit flags language or locale constraints when they are imposed without explicit opt-in or justification.

Static analysis

No suspicious patterns detected.