Back to skill

Security audit

Cyber Girlfriend

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated companion purpose, but needs Review because parts of its automatic delivery path can use local messaging credentials and read broader agent transcripts than necessary.

Review this skill before enabling it. It is designed to create recurring, owner-only companion messages, local relationship/state files, public-web searches from event context, and OpenClaw cron jobs. Do not enable custom WeChat endpoints or automatic media delivery unless you are comfortable with the credential and transcript-access risks, or patch the WeChat fallback and media recovery to use strict allowlists and dispatch-scoped files only.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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

Error
Location
scripts/companion_presence_tick.py:356
Finding

Credential-Bearing WeChat Fallback Allows a Configuration-Controlled Network Destination

Content
View full analysis
dict: """Fallback for WeChat proactive sends when CLI plugin state lacks contextToken.""" target = str(delivery.get("target") or delivery.get("owner_target") or "").strip() account_id = str(delivery.get("account") or delivery.get("accountId") or "").strip() body_text = str(text or "").strip() if not target: raise RuntimeError("weixin delivery target is required") if not body_text: raise RuntimeError("story text is required") account = load_weixin_account(account_id) context_token = load_weixin_context_token(account_id, target) if not context_token: raise RuntimeError("weixin context token is missing") package_info = load_weixin_package_info() version = str(package_info.get("version") or "0.0.0") app_id = str(package_info.get("ilink_appid") or "bot") base_url = str(account.get("baseUrl") or "https://ilinkai.weixin.qq.com").rstrip("/") + "/" token = str(account.get("token") or "").strip() client_id = f"openclaw-weixin:{int(time.time() * 1000)}-{secrets.token_hex(4)}" payload = { "msg": { "from_user_id": "", "to_user_id": target, "client_id": client_id, "message_type": 2, "message_state": 2, "item_list": [{"type": 1, "text_item": {"text": body_text}}], "context_token": context_token, }, "base_info": { "channel_version": version, "bot_agent": "OpenClaw", }, } raw_body = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8") req = urllib_request.Request( base_url + "ilink/bot/sendmessage", d ...[truncated 3298 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/companion_presence_tick.py:465
Finding

Media Recovery Scans Unrelated Main-Agent Session Transcripts

Content
View full analysis
list[Path]: if not SESSIONS_DIR.exists(): return [] candidates = [] for path in SESSIONS_DIR.glob("*.jsonl"): try: stat = path.stat() except OSError: continue modified_ms = int(stat.st_mtime * 1000) if started_after_ms and modified_ms < started_after_ms: continue candidates.append((modified_ms, path)) candidates.sort(key=lambda item: item[0], reverse=True) return [path for _, path in candidates] def extract_media_paths_from_completion_session(task_id: str, *, started_after_ms: int = 0) -> list[str]: task_ref = str(task_id or "").strip() if not task_ref: return [] paths = [] task_markers = ( task_ref, f"image_generate:{task_ref}", f"video_generate:{task_ref}", f"music_generate:{task_ref}", f"audio_generate:{task_ref}", ) for path in recent_session_jsonl_paths(started_after_ms): try: lines = path.read_text(encoding="utf-8", errors="replace").splitlines() except OSError: continue for line in reversed(lines): if not any(marker in line for marker in task_markers): continue try: row = json.loads(line) except json.JSONDecodeError: continue message = row.get("message", {}) if isinstance(row, dict) else {} if not isinstance(message, dict) or message.get("role") != "user": continue content = message.get("content") if not isinstance(content, str) or "Attachments:" not in content: ...[truncated 3144 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 (53)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description presents a full companion-building/customization capability including proactive presence delivery via cron and relationship-related behavior. The supplied code chunk only performs configuration migration and profile generation. It materializes config values, optionally imports selected owner profile fields from USER.md, generates/validates a character profile file, and writes results to disk. The module docstring explicitly states it does not create cron jobs, which directly conflicts with the declared 'OpenClaw presence cron delivery' aspect. There is also no implementation of proactive messaging, lightweight relationship memory, or companion runtime behavior in this chunk. While the code is related to the same companion domain, its actual purpose is narrower and materially different from the declared end-user functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a user-facing companion-system builder/customizer focused on persona, private-life context, memory, and proactive presence delivery. The supplied code instead implements an internal QA/release gate (validate_release.py) for validating a skill package before publication. Its primary behavior is repository validation and policy enforcement: checking file contents and structure, validating docs and examples, compiling scripts, scanning for sensitive patterns, asserting contract boundaries, and running dry-run smoke tests for related scripts. Although the script is associated with the same cyber-girlfriend project, this code chunk does not itself build/customize the companion system or deliver presence messages; it validates the release surface of that system. That is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- [references/presence-integration.md](./references/presence-integration.md)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/validate_release.py --root <SKILL_DIR> --config <CONFIG>

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code reads stored Weixin account configuration and bearer tokens from disk, reconstructs a direct HTTP request, and sends content outside the normal CLI/plugin path. This bypasses higher-level safety controls, auditing boundaries, and potentially user expectations, while enabling unauthorized or less-governed use of long-lived credentials if the skill or surrounding state is compromised.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes behavior that clearly requires powerful capabilities such as shell execution, file reads/writes, environment access, and network use, but it does not declare any explicit tool scope or permission boundary. That creates an authorization-gap risk: an agent or runtime may grant broader capabilities than users expect, making sensitive local-state changes, cron wiring, or message delivery actions insufficiently transparent or controllable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The hard rule states that day schedule events must keep 媒体信息, which imposes a specific Chinese field name as a requirement. This is a language/locale constraint presented as mandatory behavior, and the file does not offer user choice or explain a region-specific necessity for enforcing Chinese.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The default prompt uses a broad invocation phrase ('$cyber-girlfriend') without clear trigger scoping beyond the general skill name, which can increase the chance of unintended or ambiguous activation in surrounding user content. In a skill explicitly designed for proactive, intimate, owner-only interactions, accidental invocation is more dangerous because it may expose private-life context or trigger behavior in contexts where it was not intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file specifies the skill's behavior and output style exclusively in Chinese, but it does not indicate that Chinese is optional or limited to a justified region-specific use case. Under the natural-language policy rule, forcing a specific language without user opt-in is a locale policy violation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
77% confidence
Finding

This JSON config defines behavior, scheduling, and delivery settings, but it does not describe what explicit triggers or constraints cause the skill to activate. For manifest-like files, missing specificity on trigger scope can lead to unintended or overly broad invocation because there are no listed trigger phrases, boundaries, or exclusion conditions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The config fixes pronouns and timezone to Chinese-oriented values and elsewhere includes Chinese-only content, suggesting a specific language/locale experience is imposed by default. Under the policy, forcing a language or locale without user opt-in is a natural-language policy concern unless clearly documented as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The required event titles and hints are written entirely in Chinese, which implies the skill's interaction content is constrained to a single language. Because no user language preference or opt-in mechanism is shown in this file, this appears to violate the language/locale choice policy.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The schema permits arbitrary operational fields such as healthcheck_command, jobs_list_command, and cron_jobs_file inside a persona configuration. In a system that consumes this config to build shell or cron invocations, these string fields create a clear path to command injection, unsafe execution, or abuse of privileged automation, especially because this skill is described as owner-only and proactive with cron delivery.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This file presents all user-facing natural-language content in Chinese and does not indicate that the skill is region-specific or that users can opt into another language. That can violate a language/locale policy requiring user choice or explicit justification for a fixed locale.

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 · references/agent-first-time-qa-template.md (reported line 12)May include surrounding context.

md
## Core Rule

Do not ask the user to write prompts during first setup.

The agent should:
- collect routing and pacing decisions

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 · references/required-events-and-cron.md (reported line 38)May include surrounding context.

md
## Core Rule

Do not ask the user to write prompts during first setup.

The agent should:
- collect routing and pacing decisions

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The recommended opening is presented entirely in Chinese, and the rest of the scripted user-facing prompts in the template are also Chinese-language examples. The file does not state that language should match user preference or that Chinese is optional, which creates a locale/language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup instruction hard-codes a Chinese-language question, which can impose a specific language on users without opt-in. The file does not indicate that this locale restriction is optional, user-selectable, or region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The contract explicitly describes an automated flow that watches for newly generated media and sends it using the delivery contract, but it does not require an explicit user confirmation or a visible warning before generated artifacts are transmitted. In an owner-only proactive companion system handling private-life context, this increases the risk of unintended disclosure of sensitive or intimate media if the event selection, generation, or dispatch context is wrong.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The message rules explicitly require the final text to be at least 160 Chinese characters. This is a natural-language locale constraint, and the document does not offer a user opt-in/choice or explain that the skill is intentionally region-specific for compliance or similar reasons.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documentation makes public-web search mandatory for each matched private-life event, expanding the skill from a local companion/presence workflow into external network access. In this context, event-derived keywords come from intimate schedule and life-context data, so even 'public, non-sensitive' extraction can leak timing, interests, locations, or routines to third-party services and create unnecessary data exposure beyond the stated scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

A private companion presence skill does not inherently require external search to fulfill its purpose, yet the instructions require it on every event. That unjustified dependency increases attack surface, privacy risk, and operational complexity, especially because the searched terms are derived from personal event context that may reveal sensitive behavioral patterns even if not obviously secret.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document requires the schedule to contain the literal field value 必定发生:否, and later mandates 必定发生:是/否 in output. This is a natural-language locale constraint in the skill guidance, but the file does not offer user opt-in, alternatives, or a documented region-specific reason for forcing Chinese labels.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The template explicitly requires output in Chinese (你要为 companion 生成...) and later mandates a minimum length in Chinese characters. This is a natural-language locale constraint that appears unconditional and does not offer user choice or document a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The template instructs the system to derive search material from character profile, owner profile, relationship data, city, and related context, which creates a data-to-network transformation path that is broader than necessary for the feature. Although the text tries to exclude some sensitive fields, the design still encourages contextual inference that can leak private traits or relationship details indirectly through generated searches.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.