Back to skill

Security audit

life-companion

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local personal-companion skill that stores sensitive profile and journal data on the user's device, with no artifact-backed evidence of hidden exfiltration or malicious destructive behavior.

Install only if you are comfortable with a local skill keeping a long-term personal profile and journal under COMPANION_HOME. For stricter environments, set LIFE_COMPANION_NO_AUTOINSTALL=1 and install dependencies yourself, keep COMPANION_HOME in a private directory, and use the forget commands to remove stored birth, journal, or full companion data when needed.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (17)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if os.environ.get("LIFE_COMPANION_NO_AUTOINSTALL"):
        return False, "auto-install disabled (LIFE_COMPANION_NO_AUTOINSTALL=1)"
    try:
        r = subprocess.run(
            [sys.executable, "-m", "pip", "install", "--quiet", pkg],
            capture_output=True, text=True, timeout=300,
        )
Confidence
93% confidence
Finding
The code invokes `pip install` in a subprocess at runtime, which gives the skill package-execution capability and causes code from external packages to be fetched and installed during normal operation. Even though the command is passed as an argument list rather than a shell string, this still expands the trust boundary to PyPI/network/package metadata and can execute unreviewed install-time code if dependency names or package sources are compromised.

Tainted flow: 'home' from os.environ.get (line 529, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"mood_consent": bool(g("mood_consent")),
               "todo": todo,
               "ts": datetime.datetime.now().isoformat(timespec="seconds")}
    with open(os.path.join(home, ".form_result.json"), "w", encoding="utf-8") as f:
        json.dump(summary, f, ensure_ascii=False)
    return summary, "档案已建好——语言、语气、所在地都记下了。" + (
        "生辰也存好了,随时可以起命盘。" if birth_ok else "想看命盘的话,之后补上生辰就行。")
Confidence
85% confidence
Finding
The server writes sensitive onboarding results, including consent state and potentially birth-related metadata, to a path derived from --home or COMPANION_HOME without validating that the destination stays within an intended private storage directory. If an attacker can influence the environment or launch arguments, they could redirect writes to an arbitrary filesystem location accessible to the current user, causing privacy leakage or clobbering files.

Tainted flow: 'home' from os.environ.get (line 529, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
"answered": len(answers), "ts": datetime.datetime.now().isoformat(timespec="seconds")}
    _run_companion(home, "cache", "--module", "career_intake",
                   "--merge-json", json.dumps({"latest": intake}, ensure_ascii=False))
    with open(os.path.join(home, ".form_result.json"), "w", encoding="utf-8") as f:
        json.dump({"status": "career_intake", "form": "career", **intake}, f, ensure_ascii=False)
    return intake, f"测评收好了({len(answers)}/21 题 + 价值观排序)。回到对话,我就用真实职业库给你算契合度。"
Confidence
85% confidence
Finding
This file write has the same issue as the onboarding path: career intake data is persisted to a location controlled by --home or COMPANION_HOME without destination validation. Because the stored content may include personal career preferences and job aspirations, redirection to an attacker-chosen path can expose sensitive data or overwrite files under the user's account.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill instructs the agent to use shell, read/write local files, inspect environment state, and potentially access the network, but no explicit permissions are declared. That creates a real capability/expectation gap: a reviewer or runtime may treat the skill as low-privilege while it actually handles sensitive local journal/profile data and may fetch live resources or install dependencies.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose emphasizes a private one-person companion, but the file also instructs use of additional functionality: Western astrology, Zi Wei Dou Shu, synastry involving a second person's data, a localhost web server, runtime dependency installation, and safety/style gating tools. This mismatch is security-relevant because users and platform reviewers may consent to one scope while the skill actually processes broader categories of sensitive data and performs broader actions than advertised.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The module instructs the agent to derive birth-place coordinates and historical timezone data from a place name and then persist those derived attributes into the user's profile. That is a state-changing data enrichment step beyond pure chart computation, and it modifies sensitive profile data without a just-in-time consent or confirmation step tied to the write.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The skill is described as a companion for one person, but this section adds partner synastry using another person's birth data. Even though it mentions consent-gating, it expands the data model to process third-party sensitive personal data and relationship inferences, which creates a material privacy and scope-expansion risk not justified by the stated one-person design.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The skill includes built-in automatic package installation, which is not necessary for a personal companion skill's core trust model and introduces a software supply-chain risk. Runtime installation can pull and execute code from external repositories, making the agent capable of changing its environment and increasing exposure to dependency confusion, malicious packages, or compromised mirrors.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The script computes and emits `cross_person_patterns`, which correlates relationship tags across multiple named people. In a skill explicitly described as serving one person with a private on-device profile, this expands processing beyond the stated single-person scope and can reveal sensitive comparative relationship data if multiple people are present in the store. Because the domain is intimate relationship journaling, even aggregate cross-person patterning can expose private inferences about the user's history and tracked contacts.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The trigger examples include broad phrases like 'help me process this' and 'what does my day look like,' which can match ordinary conversation unrelated to this skill. Over-broad invocation is risky here because the skill is stateful, reads private profile/journal context, and may steer the conversation into sensitive onboarding or reflective analysis without the user clearly intending to invoke it.

Vague Triggers

Medium
Confidence
82% confidence
Finding
The instruction to trigger even when the user does not name a module makes activation scope ambiguous. In a memory-bearing companion skill, ambiguous routing increases the chance of unintended access to sensitive local data or unsolicited interpretation in contexts where the user may have meant a generic chat response.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The review commands expose highly sensitive journal history, tags, themes, mood, and relationship/career reflections without any explicit requirement to re-confirm user intent, warn about privacy, or limit how much data is surfaced. In a companion skill built around long-term personal profiling, this increases the risk of over-disclosure to someone glancing at the screen, sharing a device session, or triggering broader-than-expected retrieval of intimate history.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The instructions explicitly say to persist derived coordinates and timezone via profile update when only a place name is known, but they do not require a clear warning at the moment of storage. Because birthplace and birth-time metadata are highly sensitive and can increase identifiability, silently writing enriched data raises privacy and user-expectation concerns.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
This section directs caching of full chart pillars, conventions, timestamps, one-line interpretation, drill-down history, and disclaimer state into persistent module storage. That creates a durable record of highly sensitive inferred personal traits and birth-derived data without an explicit storage warning or granular retention choice at the point of caching.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This module instructs the agent to persist highly sensitive relationship data, inferred tendencies, and incident histories across time, but it does not require a clear user-facing notice describing what will be stored, how long it will persist, or who can access it. Because the data includes intimate interpersonal details and inferred psychological traits, silent or weakly disclosed persistence can create serious privacy and safety risks, especially in abusive or shared-device situations.

Session Persistence

Medium
Category
Rogue Agent
Content
#!/usr/bin/env python3
"""
form_server.py — serve a styled local HTML form, then write the result to the
user's private home (~/.companion) via companion.py.

A pure HTML file can't touch the filesystem, so this runs a tiny localhost server:
Confidence
92% confidence
Finding
This component persistently stores highly sensitive personal data, including identity details, journaling-related preferences, and optionally birth data used for profiling, in the user's home directory. In the context of a 'personal companion' skill, long-term retention materially raises privacy risk because compromise of the local account, backups, shared machines, or weak file permissions could expose an intimate behavioral profile over time.

YARA rule 'agent_skill_destructive_autonomous_actions': Autonomous destructive filesystem, shell history, or repository actions in AI agent skills [agent_skills]

High
Category
YARA Match
Content
prof = _load_yaml(p["profile"])
        prof["birth"] = {"date": None, "time": None, "time_known": None, "place": None,
                         "lat": None, "lon": None, "tz_at_birth": None,
                         "conventions": prof.get("birth", {}).get("conventions", {})}
        prof["updated"] = _today()
        _save_yaml(p["profile"], prof)
        consent = _load_yaml(p["consent"])
Confidence
83% confidence
Finding
The skill exposes a destructive recursive delete operation via `forget --all`, which removes the entire configured home directory with `shutil.rmtree(home)`. Although there is a `--yes` flag and a marker check, the command still permits large-scale irreversible deletion of local data based on an environment variable or CLI path, making accidental misuse, prompt-induced triggering, or path-manipulation mistakes highly damaging in an agent context.

Static analysis

No suspicious patterns detected.