Back to skill

Security audit

Lovefromio Ontology

Security checks for vulnerabilities and agentic risk

Overview

This skill is for local structured memory, but it should be reviewed because it writes persistent graph data while overstating validation and rollback protections.

Install only if you want a workspace-local persistent ontology memory. Do not store raw passwords, tokens, API keys, or other secrets in it, and treat validation as a manual check rather than a guarantee that bad writes are blocked. Review memory/ontology before allowing other skills to rely on or share this 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ontology.py:120
Finding

Schema Constraints Are Not Enforced Before Graph Mutations

Content
View full analysis

Vulnerability Details

File Location: scripts/ontology.py:120-137, scripts/ontology.py:163-177, scripts/ontology.py:201-213, scripts/ontology.py:250-383, scripts/ontology.py:507, and scripts/ontology.py:542
Vulnerability Type: Missing validation before persistent graph mutations
Risk Level: Medium

Vulnerable Code

Entity creation immediately appends the supplied properties to persistent storage:

python
def create_entity(type_name: str, properties: dict, graph_path: str, entity_id: str = None) -> dict:
    """Create a new entity."""
    entity_id = entity_id or generate_id(type_name)
    timestamp = datetime.now(timezone.utc).isoformat()
    
    entity = {
        "id": entity_id,
        "type": type_name,
        "properties": properties,
        "created": timestamp,
        "updated": timestamp
    }
    
    record = {"op": "create", "entity": entity, "timestamp": timestamp}
    append_op(graph_path, record)
    
    return entity

Updates are likewise committed without schema validation:

python
def update_entity(entity_id: str, properties: dict, graph_path: str) -> dict | None:
    """Update entity properties."""
    entities, _ = load_graph(graph_path)
    if entity_id not in entities:
        return None
    
    timestamp = datetime.now(timezone.utc).isoformat()
    record = {"op": "update", "id": entity_id, "properties": properties, "timestamp": timestamp}
    append_op(graph_path, record)
    
    entities[entity_id]["properties"].update(properties)
    entities[entity_id]["updated"] = timestamp
    return entities[entity_id]

Relations are also persisted without checking endpoint existence, allowed entity types, cardinality, or acyclicity:

python
def create_relation(from_id: str, rel_type: str, to_id: str, properties: dict, graph_path: str):
    """Create a relation between entities."""
    timestamp = dat
...[truncated 3368 chars]
Remediation
View remediation

Remediation Suggestions

  1. Validate proposed state before every write. Load the current graph and schema, apply the proposed mutation in memory, and run all applicable checks before calling append_op.

  2. Reject forbidden sensitive properties at the mutation boundary. For credential-like entities, reject raw passwords, secrets, tokens, private keys, and API keys before they can enter the append-only log. This check should not depend solely on an optional schema file.

  3. Validate entity operations comprehensively. Enforce:

    • Known entity types where required.
    • Required properties.
    • Forbidden properties.
    • Property types and enumeration values.
    • Unique entity IDs.
    • Valid date and datetime values.
    • Event ordering constraints.
  4. Validate relations before persistence. Confirm:

    • Both endpoint entities exist.
    • Source and destination types are permitted.
    • Cardinality remains valid.
    • The new edge does not introduce a cycle for acyclic relation types.
    • Relation properties satisfy their schema.
  5. Implement atomic mutation semantics. For multi-step transformations, validate the complete proposed state and commit it atomically. If the storage design is expanded beyond single append operations, use a temporary file and atomic replacement or a transactional database.

  6. Address secrets already written to history. Because the graph is append-only, a logical deletion does not remove historical plaintext. Rotate exposed credentials and compact or securely rewrite the graph to eliminate sensitive historical records.

  7. Align documentation with implementation. Either implement the promised pre-commit validation and rollback behavior or clearly document validation as post-hoc only. Preventive enforcement is strongly recommended for forbidden secret properties.

  8. Add regression tests. Tests should verify that invalid creates, updates, and relations produce ...[truncated 63 chars]

Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python3 scripts/ontology.py create --type Person --props '{"name":"Alice","email":"alice@example.com"}'

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/schema.md (reported line 165)May include surrounding context.

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[]?

text

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly instructs the agent to create and modify local workspace files under memory/ontology, but it does not declare any tool scope or allowed-tools boundaries. That mismatch increases the chance of unintended file writes or overbroad execution in environments that rely on manifest-declared permissions for enforcement or review.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The description contains broad triggers such as 'remember', 'what do I know about', and general cross-skill data access, which can cause the skill to activate for ordinary conversation or unrelated tasks. In a memory-writing skill, accidental invocation is risky because it can silently persist, link, or reshape user data without sufficiently specific intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The when-to-use table includes ambiguous activation conditions like 'Remember that...' and 'Skill needs shared state' without clear boundaries, making invocation overly permissive. Because this skill supports append/merge writes to persistent graph storage and cross-skill shared state, ambiguous routing can lead to unintended data retention, relation creation, or corruption of structured memory.

Content

No source excerpt is available for this finding.