Back to skill

Security audit

OpenClaw Capture

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent capture-and-notification wrapper, but it can send user content and credentials through broad, lightly constrained local and network paths without enough user control.

Review this skill before installing. It is not clearly malicious, but only use it with trusted backend URLs, HTTPS for any remote backend, tightly scoped API keys and bot tokens, and a known-safe local STT command. Avoid implicit or automatic use for private text, local image paths, videos, chat identifiers, or proprietary content unless you are comfortable sending the resulting payloads and summaries to the configured services.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/runtime/openclaw_capture_skill/dispatcher.py:222
Finding

Complete capture payload may be transmitted over unencrypted HTTP

Content
View full analysis
dict: request = urlrequest.Request( f"{self.settings.backend_url.rstrip('/')}/ingest", data=json.dumps(payload).encode("utf-8"), headers={"Content-Type": "application/json"}, method="POST", ) with urlrequest.urlopen(request, timeout=30) as resp: accepted = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis HTTP backend mode serializes and transmits the complete normalized capture payload to `OPENCLAW_CAPTURE_BACKEND_URL`. Depending on the request, that payload can contain: - Pasted text in `raw_text` - Source URLs - Image references - Chat and reply identifiers - Request identifiers and platform metadata The default endpoint uses HTTP on a loopback address, which is generally acceptable for a strictly local service. However, the configuration accepts an arbitrary URL without validating its scheme or restricting plaintext HTTP to loopback destinations. Consequently, an operator error or hostile environment configuration can direct sensitive content to a non-loopback HTTP server. The backend URL is an explicitly documented configuration option, so remote dispatch itself is within the declared functionality. The security defect is the absence of transport and destination validation, not the existence of HTTP dispatch. ### Attack Path 1. An attacker ...[truncated 998 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/runtime/openclaw_capture_skill/video_audio_bridge.py:53
Finding

Model API key is exposed through child-process command-line arguments

Content
View full analysis
str: script_path = _legacy_audio_script(legacy_project_root) return _run( [ sys.executable, str(script_path), "--url", url, "--max-seconds", str(max_seconds), "--api-key", api_key, "--api-base-url", api_base_url, "--backend", backend, ] ) ``` ### Technical Analysis The model API key is inserted into a command template as the value of `--api-key`. The bridge then forwards the same key as a command-line argument to the legacy ASR process. Although the subprocess API receives an argument list and does not invoke a shell, avoiding direct shell-metacharacter injection at this boundary, command-line arguments are not an appropriate transport for secrets. Depending on the operating system and monitoring configuration, argv values may be visible through process-inspection interfaces, administrative tools, audit systems, crash reports, or diagnostic telemetry. The credential is passed through more than one process boundary, increasing the ti ...[truncated 1132 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/runtime/openclaw_capture_skill/notifiers.py:149
Finding

Telegram bot token may be exposed through unsanitized notification errors

Content
View full analysis
None: if not self.telegram_bot_token: raise RuntimeError("telegram output selected but OPENCLAW_CAPTURE_TELEGRAM_BOT_TOKEN is missing") _post_urlencoded( f"https://api.telegram.org/bot{self.telegram_bot_token}/sendMessage", payload, ) ``` ```python # scripts/runtime/openclaw_capture_skill/dispatcher.py try: notifier = self._build_fanout_notifier(legacy_cfg=legacy_cfg) notifier.send_from_job_result(payload, job, skip_outputs=skip_outputs) except Exception as exc: job.setdefault("warnings", []).append(f"wrapper_notification_error: {exc}") result = job.setdefault("result", {}) if isinstance(result, dict): result["notification_error"] = str(exc) ``` ```python # scripts/runtime/openclaw_capture_skill/cli.py job = dispatcher.dispatch(payload) print(json.dumps(job, ensure_ascii=False, indent=2)) ``` ### Technical Analysis Telegram's Bot API requires the bot token to appear in the request path. The implementation constructs a URL containing the token and passes it directly to `urllib`. Notification exceptions are caught and copied verbatim into two externally visible job fields. The complete job is then printed by the CLI. If a transport implementation, proxy, runtime wrapper, or diagnostic layer includes the request URL in an exception message, the token-bearing URL may consequently be persisted in logs or returned to callers. The current code does not guarantee that every exception includes the URL, so disclosure depe ...[truncated 1208 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (22)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/runtime/openclaw_capture_skill/config.py (reported line 87)May include surrounding context.

python
elif legacy_project_root and (legacy_project_root / "config.json").exists():
            legacy_config_path = (legacy_project_root / "config.json").resolve()
        legacy_env_path = None
        if legacy_project_root and (legacy_project_root / ".env").exists():
            legacy_env_path = (legacy_project_root / ".env").resolve()
        return cls(
            skill_root=skill_root,

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/runtime/openclaw_capture_skill/config.py (reported line 88)May include surrounding context.

python
elif legacy_project_root and (legacy_project_root / "config.json").exists():
            legacy_config_path = (legacy_project_root / "config.json").resolve()
        legacy_env_path = None
        if legacy_project_root and (legacy_project_root / ".env").exists():
            legacy_env_path = (legacy_project_root / ".env").resolve()
        return cls(
            skill_root=skill_root,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs use of shell execution, environment variables, local file paths, networked backends, and external output channels, but it does not declare any explicit tool scope or permission boundaries. This creates an over-privileged integration surface where an agent may access sensitive local resources or transmit data externally without clear least-privilege constraints or user visibility.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is designed to capture user-provided links, text, images, and videos, then send data through a backend and fan results out to Telegram and Feishu, but the description does not warn users that their content may be transmitted to external services and notification endpoints. This lack of disclosure undermines informed consent and can lead to unintended leakage of sensitive content, credentials, personal data, or proprietary media.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill enables implicit invocation without any visible activation constraints, which can cause the agent to trigger this skill in response to loosely related user input. Because this skill dispatches local capture jobs and routes results to external channels, over-broad triggering increases the risk of unintended local workflow execution and unintended data exfiltration to Telegram or Feishu.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation explicitly describes sending capture payloads to a remote backend and using remote STT fallback, but it does not warn users that captured content, links, text, images, videos, or audio may leave the local system. In the context of a capture-and-fanout skill, this omission increases the risk of unintended disclosure of sensitive user data to third-party services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
82% confidence
Finding

The file documents default model API endpoints for external providers, which indicates captured or derived content may be sent to third-party services. While using external APIs is not inherently malicious, in this skill's context it is security-relevant because the skill processes potentially sensitive captured data and the documentation does not pair these endpoints with privacy, consent, or data-handling warnings.

Content

Scanner excerpt · references/runtime-profiles.md (reported line 26)May include surrounding context.

md
## Model Profile

- `openai_direct`
  - Default base URL: `https://api.openai.com/v1`
- `aihubmix_gateway`
  - Default base URL: `https://aihubmix.com/v1`

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/runtime/openclaw_capture_skill/config.py (reported line 34)May include surrounding context.

python
def _default_model_api_base_url(model_profile: str) -> str:
    if model_profile == "openai_direct":
        return "https://api.openai.com/v1"
    return "https://aihubmix.com/v1"

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The payload normalization unconditionally defaults requested_output_lang to "zh-CN" when the user does not provide a language. This imposes a specific locale by default rather than offering a neutral default or explicit user choice.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest describes a wrapper skill that captures content, routes STT, and fans results out, but this code also configures command-line execution of helper scripts for video subtitle, audio, and keyframe extraction. Spawning external commands is a stronger capability than simple dispatch/orchestration and is not explicitly justified by the stated wrapper purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code performs a POST request to an external/backend URL with the entire payload, which may include user content such as raw_text, source_url, chat identifiers, or image references. While there is a module docstring about HTTP mode, there is no confirmation prompt, logging, or explicit user-facing warning here that data will be transmitted over the network.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code emits fixed Chinese strings such as "未命名内容", "一句话总结", and other section headings regardless of user preference or environment. That creates a language/locale policy issue because the skill enforces a specific language without offering a choice or documenting a justified regional scope.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This code constructs multiple user-visible summary fields entirely in Chinese, including bullets, follow-up actions, and default titles/conclusions. That imposes a specific language on all users without opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The ingest namespace assigns "zh-CN" as the default requested_output_lang when no user preference is provided. This forces a specific locale by default rather than offering a choice or requiring explicit opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code posts notification payloads to Telegram and Feishu, and the transmitted text is built from ingest, summary, note path, structure map, open URL, and evidence data. There is no confirmation prompt, print/log statement, or explanatory comment/docstring near the outbound requests to disclose that user or system-derived content will be sent to external services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/runtime/openclaw_capture_skill/notifiers.py (reported line 153)May include surrounding context.

python
if not self.telegram_bot_token:
            raise RuntimeError("telegram output selected but OPENCLAW_CAPTURE_TELEGRAM_BOT_TOKEN is missing")
        _post_urlencoded(
            f"https://api.telegram.org/bot{self.telegram_bot_token}/sendMessage",
            payload,
        )

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/runtime/openclaw_capture_skill/video_audio_bridge.py (reported line 18)May include surrounding context.

python
def _run(args: list[str]) -> str:
    try:
        result = subprocess.run(args, check=True, capture_output=True, text=True)
    except subprocess.CalledProcessError as exc:
        stderr = (exc.stderr or "").strip()
        stdout = (exc.stdout or "").strip()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The code forwards the API key and base URL directly to child processes, including legacy scripts and potentially configurable local tooling. This broadens exposure of sensitive credentials to other executables and code paths, and if those subprocesses are untrusted, compromised, or verbose in logging/error handling, the key may be disclosed or misused.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill executes a configurable local_stt_command after formatting it with runtime values and splitting it into argv, which allows arbitrary local program execution under the agent's privileges. In a skill whose stated purpose is transcription routing, this materially expands capability from STT selection to unrestricted command execution, making hostile or tampered configuration able to run arbitrary binaries and potentially exfiltrate data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The instruction requires the skill to immediately tell the user 已收到,开始处理。, which enforces a Chinese response regardless of the user's language preference. This is a natural-language locale policy concern because no opt-in or language-selection behavior is described.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This code file calls Settings.from_env(), which indicates access to environment-provided configuration and potentially sensitive credentials. The CLI provides no confirmation, log message, comment, or docstring warning that environment values may be read during execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The settings loader reads a model API key, Telegram bot token, and Feishu webhook from environment variables. This is access to sensitive credentials, but the file provides no confirmation, logging, comment, or docstring explaining that the skill consumes these secrets.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.