Back to skill

Security audit

screen-life

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent activity-reporting purpose, but it under-discloses sensitive uploads and installs persistent background execution with unsafe scoping.

Review this carefully before installing. It is intended to monitor daily computer activity, including potentially sensitive browser/search/note/app/AI usage, and it creates a persistent macOS background agent. Do not install unless you are comfortable with that monitoring, have checked the LaunchAgent target script, and understand that reports may be sent to an LLM endpoint or webhook despite the local-only privacy statement.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (4)

T06 · System Persistence

Error
Location
install.sh:45
Finding

Persistent LaunchAgent with Automatic Restart

Content
View full analysis
"$PLIST_PATH" << PLIST Label com.screen-life.daemon ProgramArguments $PYTHON $SCRIPTS_DIR/activity_daemon.py RunAtLoad KeepAlive StandardOutPath $MONITOR_HOME/daemon.log StandardErrorPath $MONITOR_HOME/daemon.err PLIST launchctl load "$PLIST_PATH" 2>/dev/null || launchctl bootstrap gui/$UID "$PLIST_PATH" 2>/dev/null || true ``` ### Technical Analysis The installer creates a macOS LaunchAgent in `~/Library/LaunchAgents`, configures it to run automatically at login through `RunAtLoad`, and instructs launchd to restart it continuously through `KeepAlive`. A user-level LaunchAgent is related to the Skill's advertised always-on monitoring functionality and does not require root privileges. However, `KeepAlive` creates stronger persistence than is necessary for on-demand or periodically scheduled report generation. The service survives the original Skill invocation and subsequent login sessions. The command also suppresses all launchctl errors and ends with `|| true`. Consequently, the installer always reports that the daemon started successfully, even if service registration failed. This prevents users from accurately determining whether persistent monitoring is active. ### At ...[truncated 950 chars]
Remediation
View remediation

T06 · System Persistence

Error
Location
install.sh:10
Finding

Persistent Execution of Unverified Code from a Shared User Directory

Content
View full analysis
"$PLIST_PATH" << PLIST Label com.screen-life.daemon ProgramArguments $PYTHON $SCRIPTS_DIR/activity_daemon.py ``` ### Technical Analysis The installer treats the existence of `~/.orbitos-monitor/scripts` as sufficient evidence that its contents are trusted. It does not validate the origin, ownership, permissions, type, contents, or cryptographic digest of `activity_daemon.py`. It then configures a persistent LaunchAgent to execute that path. The audited package does not contain the referenced `daemon.py`. On a fresh installation, the `cp "$SKILL_DIR/daemon.py"` command therefore fails under `set -e`. If the shared scripts directory already exists, copying is skipped and the installer instead relies on whatever `activity_daemon.py` is already present there. T ...[truncated 1531 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
handler.py:74
Finding

Behavioral Reports and API Credentials Can Be Sent to an Arbitrary LLM Endpoint

Content
View full analysis
dict | None: """ 读取 LLM 配置,仅使用 OpenClaw 运行时注入的环境变量: OPENCLAW_LLM_API_KEY — API 密钥 OPENCLAW_LLM_BASE_URL — 接口地址(兼容标准 Chat Completions 格式) OPENCLAW_LLM_MODEL — 模型标识 未注入时返回 None,跳过 AI 分析。 """ api_key = os.getenv("OPENCLAW_LLM_API_KEY") if not api_key: return None base_url = os.getenv("OPENCLAW_LLM_BASE_URL", "").rstrip("/") if not base_url: return None model = os.getenv("OPENCLAW_LLM_MODEL", "").split("/")[-1] if not model: return None return {"api_key": api_key, "base_url": base_url, "model": model} def run_llm_analysis(report_path: Path | None, fallback_text: str) -> str: """用 LLM 对日报做洞察分析,返回 AI 段落;未配置时返回空字符串""" cfg = _get_llm_config() if not cfg: return "" # 优先读完整 markdown,降级用 stdout 摘要 if report_path and report_path.exists(): content = report_path.read_text(encoding="utf-8")[:4000] else: content = fallback_text[:3000] try: import requests as _req resp = _req.post( f"{cfg['base_url']}/chat/completions", headers={ "Authorization": f"Bearer {cfg['api_key']}", "Content-Type": "application/json", }, json={ "model": cfg["model"], "messages": [ { "role": "system", "content": ( "你是一个个人效率分析助手。根据用户的电脑行为数据," "给出简洁的洞察和建议。用中文回复,不超过 250 字。" ), }, { ...[truncated 2396 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
handler.py:240
Finding

Feishu Push Accepts an Unvalidated Webhook Destination

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (37)

Tainted flow: 'url' from os.getenv (line 233, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The function transmits the generated activity report to a webhook URL from an environment variable with no destination allowlist, no content minimization, and no user-facing warning about external exfiltration. Because the report may contain sensitive behavioral data, any configured or attacker-controlled webhook can receive private usage information outside the local reporting scope described by the skill.

Content

Scanner excerpt · handler.py (reported line 238)May include surrounding context.

python
print("⚠️  未设置 FEISHU_WEBHOOK_URL,跳过推送")
        return
    import requests
    requests.post(url, json={"msg_type": "text", "content": {"text": content}})
    print("✅ 已推送到飞书")

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose emphasizes local daily monitoring and reporting, but the documented behavior also includes sending detailed behavior-report content to an external LLM API and pushing reports to Feishu. This mismatch is dangerous because users may consent to local analytics while unaware that highly sensitive activity summaries, browsing/search patterns, note changes, and AI usage data can leave the device.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill performs background monitoring of sensitive sources including browser history, search terms, note-change metadata, and AI usage summaries, but the description does not present a clear upfront warning before installation and use. In this context, the lack of prominent privacy disclosure materially increases the risk of uninformed consent and accidental collection or exposure of highly personal behavioral data.

Content

No source excerpt is available for this finding.

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 · handler.py (reported line 19)May include surrounding context.

python
# 加载 .env(优先级最低,会被已设置的环境变量覆盖)
try:
    from dotenv import load_dotenv
    load_dotenv(Path(__file__).parent / ".env", override=False)
except ImportError:
    pass

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill is described as local silent monitoring/reporting, but this code sends report contents to an external LLM service and also supports external webhook delivery. That mismatch is dangerous because users may reasonably expect local-only processing while sensitive computer-activity summaries are actually transmitted off-device.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares capabilities that include environment access, file reads, network use, and shell execution, but it does not define any explicit tool scope or permission boundaries. For a background-monitoring skill that handles sensitive behavioral data and can call external services, this missing least-privilege declaration increases the chance of overbroad access and unsafe execution in the host environment.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation text is broad enough that the skill could trigger whenever a user asks about what they did today, productivity, or app usage, despite the skill involving background monitoring and potentially sensitive data processing. Ambiguous triggering raises the risk of unexpected activation, unintended exposure of private activity summaries, and use in contexts where the user did not mean to invoke monitoring-derived data.

Content

No source excerpt is available for this finding.

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 · handler.py (reported line 50)May include surrounding context.

python
cmd += ["--format", "json"]

    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        stdout = result.stdout or result.stderr
        return stdout, _parse_report_path(stdout)
    except (subprocess.TimeoutExpired, FileNotFoundError):

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code silently consumes runtime API credentials and prepares outbound LLM use for analyzing sensitive activity reports, which is not clearly necessary for basic report viewing. In a monitoring skill, hidden cloud analysis increases privacy risk because detailed user-behavior data may leave the machine without strong user awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The function sends report content to an external LLM without a clear user-facing warning at the moment of transmission. Since the report summarizes computer activity and may include sensitive personal or work patterns, undisclosed cloud transmission creates a meaningful privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Feishu push introduces an external sharing capability beyond the stated purpose of viewing and analyzing local daily activity. That broadens the data exposure surface, especially because the content being pushed may include sensitive summaries of user behavior and application usage.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The push feature transmits the full output externally without warning that personal activity data is leaving the local system. In the context of a silent-monitoring skill, that lack of disclosure materially increases privacy harm because the report content is inherently sensitive.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
92% confidence
Finding

This is a real external-transmission path that posts report content to a webhook. In a skill that monitors user activity, exporting the generated report can leak sensitive personal or enterprise behavior data to third parties, especially if the endpoint is misconfigured or malicious.

Content

Scanner excerpt · handler.py (reported line 238)May include surrounding context.

python
print("⚠️  未设置 FEISHU_WEBHOOK_URL,跳过推送")
        return
    import requests
    requests.post(url, json={"msg_type": "text", "content": {"text": content}})
    print("✅ 已推送到飞书")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The installer creates a persistent LaunchAgent and immediately starts a background daemon for ongoing activity monitoring, but it does not present a clear, explicit consent warning before doing so. In the context of a skill whose purpose is to silently monitor daily computer behavior, this increases privacy risk and can lead to users unknowingly enabling continuous surveillance-like behavior.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

This line begins creation of a LaunchAgent plist used to establish session persistence. Persistence is not inherently malicious, but in this monitoring skill it enables continuous background execution across logins, which is privacy-sensitive and dangerous when installed without strong disclosure and consent.

Content

Scanner excerpt · install.sh (reported line 40)May include surrounding context.

sh
echo "  ✅ 已复制内置守护脚本"
  fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 41)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 43)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 45)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 65)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 80)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 81)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 97)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 98)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 41)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 45)May include surrounding context.

sh
fi

  # 创建 launchd plist
  PLIST_PATH="$HOME/Library/LaunchAgents/com.screen-life.daemon.plist"
  PYTHON=$(which python3)
  cat > "$PLIST_PATH" << PLIST
<?xml version="1.0" encoding="UTF-8"?>

Static analysis

No suspicious patterns detected.