Back to skill

Security audit

Ontology Local

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local persistent knowledge graph, but its broad memory triggers and unenforced validation claims need review before use.

Install only if you want a shared local memory graph in the workspace. Do not store passwords, API keys, tokens, or other secrets in ontology properties, and treat validation as a manual check rather than an enforced safety boundary. Review memory/ontology/graph.jsonl before sharing, syncing, or backing up the workspace.

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:104
Finding

Graph Mutations Are Persisted Without Pre-Commit Constraint Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/ontology.py, lines 104-119
Vulnerability Type: Missing validation before persistent storage
Risk Level: Medium

The skill states that every mutation is validated against type constraints before being committed. However, entity creation immediately appends attacker-controlled properties to the persistent JSONL graph without loading or applying the configured schema.

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

The same unsafe persistence pattern is also present in update_entity at lines 154-169 and create_relation at lines 179-192. Validation is only available as a separate validate command and therefore occurs after data has already been committed. Moreover, validation only reports errors; it does not roll back or remove invalid records.

Technical Analysis

The CLI accepts user-controlled JSON through --props and passes it directly to mutation functions. create_entity constructs a record and invokes append_op without calling load_schema, validate_graph, or any equivalent per-mutation validator.

This breaks the documented security boundary for sensitive ontology types. For example, the documented Credential schema requires indirect secret references and forbids properties such as password, secret, token, key, and api_key. A caller can nevertheless store those fields directly in the plaintext graph.

Relation ...[truncated 2509 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate every proposed mutation before appending it:

    • Load the configured schema.
    • Apply the mutation to an in-memory copy of the current graph.
    • Run all entity, relation, cardinality, reference, and acyclicity checks.
    • Append the operation only if validation succeeds.
  2. Add dedicated mutation validators rather than invoking only whole-graph validation:

    • Verify required, forbidden, and enum-constrained properties on create and update.
    • Reject unknown or malformed entity structures.
    • Ensure both relation endpoints exist.
    • Enforce relation endpoint types, cardinality, and acyclicity before writing.
  3. Install a secure default schema as executable configuration rather than leaving the reference definitions solely in Markdown. Fail closed for sensitive types when the schema is missing or malformed.

  4. Explicitly reject secret-bearing property names for Credential entities even when no custom schema exists. Consider recursively detecting prohibited fields to prevent secrets from being nested under another object.

  5. Use an atomic commit process. Write the validated operation to a securely created temporary file, flush it, and atomically replace or append under an appropriate file lock to prevent concurrent check-to-write races.

  6. Return a nonzero exit status on rejected mutations and validation failures so calling agents cannot mistake invalid operations for successful commits.

  7. Add regression tests covering forbidden credential fields, missing required fields, invalid enum values, nonexistent relation endpoints, type mismatches, cardinality violations, cycles, and concurrent mutations.

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
93% confidence
Finding

The skill explicitly describes write operations to workspace storage (memory/ontology/graph.jsonl, schema.yaml) and even directory creation, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch increases the risk of unintended or unauthorized file modification if the agent auto-invokes the skill in contexts where users did not expect persistent writes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are very broad (remember, what do I know about, entity CRUD, cross-skill data access) and can match common conversational requests, causing the skill to activate in many contexts. Because this skill persists and links structured data across skills, over-broad activation can lead to unintended memory creation, privacy issues, or state corruption beyond the user's intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The delete_entity function performs a persistent deletion by appending a delete operation to the graph log, but there is no confirmation prompt or in-function warning around this destructive action. Although the CLI later prints a success message after deletion, that does not warn the user before the irreversible state change occurs.

Content

No source excerpt is available for this finding.