Back to skill

Security audit

Ontology Causal Enhanced

Security checks for vulnerabilities and agentic risk

Overview

The skill is not clearly malicious, but it asks agents to log and backfill broad personal activity history with weak scoping and unsafe temporary-file handling.

Install only if you intentionally want a local memory system that records actions and can import email, calendar, and message history. Before use, narrow when the causal skill runs, avoid bulk backfill unless explicitly needed, review or patch the fixed /tmp export paths, and define retention/deletion rules for memory/causal and memory/ontology data.

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
skills/causal-md/scripts/backfill_email.py:167
Finding
Predictable Temporary File Exposes Email History and Permits Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `skills/causal-md/scripts/backfill_email.py`, lines 167-172 **Vulnerability Type**: Predictable temporary file, insecure permissions, missing cleanup, and symlink following **Risk Level**: Medium ### Vulnerable Code ```python # Write to temp and process tmp_path = "/tmp/gog_sent_emails.json" with open(tmp_path, "w") as f: json.dump(sent_emails, f) return backfill_from_json(tmp_path, log_path, all_emails) ``` ### Technical Analysis The email backfill process writes exported email data to the fixed path `/tmp/gog_sent_emails.json`. The file is opened with normal write mode, which: - Does not create the file exclusively. - Follows an existing symbolic link. - Uses permissions derived from the process umask rather than explicitly enforcing owner-only access. - Leaves the exported data on disk after processing. - Reuses the same globally predictable path for every invocation. The subprocess invocation itself uses an argument array without `shell=True`, so no command-injection vulnerability was identified. The vulnerability arises from how its sensitive output is subsequently stored. On a shared system, another local account can predict and monitor this path. If the resulting permissions allow access, that account may read the retained email export. An attacker may also pre-create the path as a symbolic link. If operating-system symlink protections do not block the operation and the victim can write to the target, opening the path with `"w"` truncates and overwrites the target with JSON. ### Attack Path 1. A local attacker determines that the victim uses the email backfill script. 2. The attacker monitors `/tmp/gog_sent_emails.json` or pre-creates it as a symbolic link to another file writable by the victim. 3. The victim executes `backfill_email.py --days ...`. 4. The script retrieves sent-email records through `gog`. 5. The script opens the predictable path in truncating write mode and writes the ex ...[truncated 919 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Avoid creating a temporary file because `sent_emails` is already available in memory. Refactor the processing function to accept parsed records directly. If a temporary file is genuinely required: 1. Use `tempfile.NamedTemporaryFile` or `tempfile.TemporaryDirectory`. 2. Create the file with exclusive, race-resistant semantics. 3. Enforce owner-only mode `0600`. 4. Keep the temporary file inside a directory accessible only to the current user. 5. Delete it in a `finally` block, including when JSON parsing or backfill processing fails. 6. Do not reuse a fixed filename. 7. Avoid following attacker-controlled symbolic links. Example: ```python import os import tempfile tmp_path = None try: with tempfile.NamedTemporaryFile( mode="w", prefix="gog_sent_emails_", suffix=".json", delete=False, encoding="utf-8", ) as tmp: tmp_path = tmp.name os.chmod(tmp_path, 0o600) json.dump(sent_emails, tmp) return backfill_from_json(tmp_path, log_path, all_emails) finally: if tmp_path: try: os.unlink(tmp_path) except FileNotFoundError: pass ``` The preferred design is to eliminate the temporary export entirely. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skills/causal-md/scripts/backfill_calendar.py:173
Finding
Predictable Temporary File Exposes Calendar History and Permits Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `skills/causal-md/scripts/backfill_calendar.py`, lines 173-177 **Vulnerability Type**: Predictable temporary file, insecure permissions, missing cleanup, and symlink following **Risk Level**: Medium ### Vulnerable Code ```python tmp_path = "/tmp/gog_calendar.json" with open(tmp_path, "w") as f: f.write(result.stdout) return backfill_from_json(tmp_path, log_path) ``` ### Technical Analysis The calendar backfill process writes the complete output returned by `gog calendar list` to the fixed path `/tmp/gog_calendar.json`. Normal `open(..., "w")` follows symbolic links and truncates an existing target. The implementation does not use exclusive creation, explicitly set owner-only permissions, generate an unpredictable filename, or remove the export after processing. Consequently, sensitive calendar data can remain in a shared temporary directory beyond the lifetime of the command. The `gog` subprocess call is constructed as an argument list without a shell and was not found to be susceptible to shell command injection. ### Attack Path 1. A local attacker predicts the hard-coded path `/tmp/gog_calendar.json`. 2. The attacker monitors the path or creates it as a symbolic link to a file writable by the victim. 3. The victim runs the calendar backfill command. 4. The script retrieves calendar history through `gog`. 5. The script opens the predictable path in truncating write mode and writes the complete command output. 6. If permissions permit, the attacker reads the retained calendar export. If applicable host symlink protections do not prevent it, the linked target is overwritten. 7. The script does not remove the temporary file after parsing. ### Impact Assessment The vulnerability is local and does not independently provide privilege escalation. Potential consequences include: - Disclosure of calendar records returned by `gog`, potentially including event times, attendees, conferencing information, ...[truncated 460 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Prefer parsing `result.stdout` directly instead of writing it to disk: ```python events = json.loads(result.stdout) return backfill_from_records(events, log_path) ``` If disk-backed processing is required: 1. Use Python's `tempfile` module to generate an unpredictable path. 2. Create the file exclusively with owner-only permissions. 3. Place it in a private temporary directory. 4. Remove the file in a `finally` block. 5. Ensure cleanup occurs on parsing errors and interrupts. 6. Never use a shared, constant filename for calendar exports. 7. Minimize the fields written to disk where possible. A secure temporary-file implementation should use mode `0600` and avoid following pre-existing symbolic links. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skills/causal-md/scripts/backfill_messages.py:161
Finding
Predictable Temporary File Retains Full Messaging Export and Permits Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `skills/causal-md/scripts/backfill_messages.py`, lines 161-165 **Vulnerability Type**: Predictable temporary file containing sensitive message history, insecure permissions, missing cleanup, and symlink following **Risk Level**: Medium ### Vulnerable Code ```python tmp_path = "/tmp/wacli_messages.json" with open(tmp_path, "w") as f: json.dump(all_messages, f) return backfill_from_json(tmp_path, log_path, "whatsapp", all_messages) ``` ### Technical Analysis The WhatsApp backfill implementation writes `all_messages` to the fixed path `/tmp/wacli_messages.json`. Unlike the derived causal action log, this temporary export may contain complete message records, including message bodies and conversation metadata returned by `wacli`. The file is created using ordinary truncating write mode. This does not provide exclusive creation, follows existing symbolic links, relies on the current umask for permissions, and leaves the export on disk indefinitely after processing. The predictable location makes local monitoring or path pre-placement practical on a shared host. The `wacli` subprocess invocation uses a fixed executable and an argument array without `shell=True`; no shell command-injection path was identified. ### Attack Path 1. A local attacker learns or predicts that the victim will use the WhatsApp backfill feature. 2. The attacker monitors `/tmp/wacli_messages.json` or places a symbolic link at that path. 3. The victim invokes `backfill_messages.py --platform whatsapp`. 4. The script retrieves up to 1,000 message records through `wacli`. 5. The complete parsed message collection is serialized to the predictable temporary path. 6. If file permissions permit, the attacker reads the retained export. If applicable symlink protections do not block the operation, a victim-writable symlink target is truncated and replaced with message JSON. 7. No cleanup removes the sensitive export after causal features h ...[truncated 776 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not serialize the complete message collection to a temporary file. Refactor `backfill_from_json` into a record-oriented function and pass `all_messages` directly: ```python return backfill_from_records( all_messages, log_path, "whatsapp", all_messages, ) ``` If a temporary artifact cannot be avoided: 1. Use `tempfile.NamedTemporaryFile` or a private `TemporaryDirectory`. 2. Generate a unique, unpredictable filename. 3. Create it exclusively and set mode `0600`. 4. Remove it reliably in a `finally` block. 5. Limit the stored fields to those required for causal derivation. 6. Consider processing messages incrementally to reduce the sensitive data footprint. 7. Document the retention policy and ensure no raw message export remains after successful or failed execution. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (51)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
This variant asserts the reverse mismatch—ontology present but causal capability absent—and the markdown does not provide enough proof of meaningful causal inference beyond a named estimation script. While not an exploit by itself, inaccurate capability claims are still a security-relevant trust issue, particularly when the skill stores user data and may influence decisions.

Ae1

High
Category
analysis-evasion
Content
python3 skills/ontology-md/scripts/ontology.py create --type Person --props '{"name":"Alice"}'
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 skills/ontology-md/scripts/ontology.py create --type Person --props '{"name":"Alice"}'
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 skills/ontology-md/scripts/ontology.py create --type Person --props '{"name":"Alice"}'
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python3 skills/ontology-md/scripts/ontology.py create --type Person --props '{"name":"Alice"}'
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

High
Confidence
98% confidence
Finding
The trigger metadata says to activate on 'ANY high-level action with observable outcomes,' which is extremely broad and likely to invoke the skill on routine user activity. Overbroad triggering can silently expand logging, analysis, and decision influence into many contexts the user did not intend, increasing privacy and operational risk.

Vague Triggers

High
Confidence
99% confidence
Finding
The trigger section explicitly covers unrestricted 'ANY high-level action' across communications, calendar, tasks, files, social, purchases, and system changes. This lack of scope boundaries makes accidental invocation and collection of unrelated activity highly likely, especially in environments where the agent can observe or execute many actions.

Credential Access

High
Category
Privilege Escalation
Content
forbidden_properties: [password, secret, token, key, api_key]
  properties:
    service: string
    secret_ref: string  # Reference to secret store (e.g., "keychain:github-token")
    expires: datetime?
    scope: string[]?
```
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises shell execution and file-writing behavior through its documented commands, but it does not declare any tool scope such as allowed-tools or permissions. That creates an authorization and review gap: users and orchestrators cannot easily tell that the skill can execute local commands and persist data, increasing the chance of unintended command execution or data modification.

Vague Triggers

Medium
Confidence
96% confidence
Finding
Trigger phrases such as '记住', 'what do I know', or 'show dependencies' are broad, natural-language expressions that can arise in ordinary conversation. In a skill that writes persistent knowledge and action history, overly generic triggers increase the risk of accidental activation, unintended storage of sensitive data, and unauthorized modifications to local memory.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly stores entities, credentials, devices, messages, notes, and action history in persistent local files, but the markdown provides no warning about sensitivity, retention, access control, or consent. This is dangerous because users may unknowingly persist secrets, personal data, or communication metadata to disk where it can later be exposed, reused, or mishandled.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill is framed as causal reasoning support, but it expands into broad collection and reconstruction of historical user activity across email, calendar, messaging, files, and purchases. That creates a capability mismatch: a reasoning layer does not inherently require indiscriminate cross-domain data harvesting, and the broad data access materially increases privacy and abuse risk.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The backfill section instructs use of external tools to export sent emails, calendar events, and message history into temporary files for later processing. This can expose sensitive communications metadata and content without clear necessity, consent boundaries, minimization, or handling safeguards, making overcollection and data leakage more likely.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The backfill guidance directs extraction and parsing of historical communications and calendar data without any user-facing privacy warning, consent flow, or disclosure of what will be stored. Historical communications are often sensitive, and bulk retrospective access creates substantial confidentiality and compliance risk.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The required action log stores structured records of user actions, context, pre-state, post-state, and outcomes in persistent local memory, but the skill does not warn that this may contain sensitive behavioral or communication data. Persistent telemetry without notice, minimization, or retention controls can create privacy exposure and forensic value for attackers.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
Although presented as a reasoning aid, the workflow gives the skill authority to influence or control execution-time decisions, including ranking actions, executing the 'best' action, and refusing or escalating based on its own thresholds. That increases the blast radius from advisory analysis to operational autonomy, which can cause unintended actions or denials if the model is wrong or manipulated.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The script persistently backfills user calendar history into an action log under memory/causal/action_log.jsonl, which materially expands the skill from ontology/causal inference into collection and retention of behavioral history. That creates a privacy and data-minimization risk because sensitive scheduling metadata is stored long-term without clear consent, retention limits, or scope justification.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script writes derived calendar metadata such as meeting times, attendee counts, recurrence, and video presence into a persistent local action log without any warning that this data may be sensitive. Even if full event contents are not stored, this behavioral log can reveal patterns about work, relationships, and routines if accessed by other tools or users on the system.