Back to skill

Security audit

Ontology To Expertpack

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent converter, but it can turn private ontology memory into shareable files while only partially filtering secrets and copying untrusted content into Markdown.

Install only if you are comfortable reviewing the generated pack before sharing it. Run it on a copy of your ontology graph, use a fresh empty output directory, inspect for secrets and injected instructions, and do not publish the result until sensitive content has been removed.

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

Error
Location
scripts/convert.py:66
Finding

Incomplete Sensitive-Data Filtering Can Export Credentials

Content
View full analysis
**Lead summary:** {etype} record from ontology graph.") md.append(f"\n**Type:** {etype}") for k, v in props.items(): md.append(f"- **{k}:** {v}") ``` ### Technical Analysis The sanitization routine examines only top-level property names. It does not recursively inspect nested dictionaries, arrays, or serialized objects. Consequently, a secret stored under a benign top-level key remains intact. For example, the following property is not removed: ```json { "details": { "token": "sensitive-value" } } ``` The filter also relies on a limited substring list. Sensitive fields such as `mnemonic`, `seed_phrase`, `authorization`, `bearer`, `session`, or `client_secret_value` may not be handled reliably. Values themselves are never inspected for recognizable credential patterns. After this incomplete filtering, Python converts arbitrary nested values to strings and writes them to generated Markdown files. The skill documentat ...[truncated 1343 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert.py:138
Finding

Untrusted Ontology Data Is Embedded into Markdown Without Neutralization

Content
View full analysis
**Lead summary:** {etype} record from ontology graph.") md.append(f"\n**Type:** {etype}") for k, v in props.items(): md.append(f"- **{k}:** {v}") # Add relations for this entity outgoing = [r for r in relations if r.get('from') == eid] if outgoing: md.append("\n**Relations:**") for r in outgoing: to_id = r.get('to') to_label = entity_map.get(to_id, (to_id, ''))[0] if to_id in entity_map else to_id md.append(f"- {r.get('rel', 'relates_to')} → [{to_label}](../{entity_map.get(to_id, ('', ''))[1]})" if to_id in entity_map else f"- {r.get('rel', 'relates_to')} → {to_label}") ``` ### Technical Analysis The converter treats entity labels, types, property keys, property values, and relationship names as trusted Markdown. These fields originate in the input ontology graph and are interpolated into generated documents without escaping or structural validation. A malicious or compromised graph can therefore introduce: - New Markdown headings or sections. - Misleading links and images. - Raw HTML supported by some Markdown renderers. - Text that visually impersonates generated metadata. - Instruction-like content designed to influence an AI agent that retrieves the ExpertPack. The project explicitly produces a pack intended for multi-layer retrieval and AI consumption. As a result, adversarial text embedded in source records can become ...[truncated 1568 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert.py:118
Finding

Normalized Filename Collisions Cause Silent Entity Overwrites

Content
View full analysis
**Lead summary:** {etype} record from ontology graph.") md.append(f"\n**Type:** {etype}") for k, v in props.items(): md.append(f"- **{k}:** {v}") # Add relations for this entity outgoing = [r for r in relations if r.get('from') == eid] if outgoing: md.append("\n**Relations:**") for r in outgoing: to_id = r.get('to') to_label = entity_map.get(to_id, (to_id, ''))[0] if to_id in entity_map else to_id md.append(f"- {r.get('rel', 'relates_to')} → [{to_label}](../{entity_map.get(to_id, ('', ''))[1]})" if to_id in entity_map else f"- {r.get('rel', 'relates_to')} → {to_label}") md_content = '\n'.join(md) file_path.write_text(md_content, encoding='utf-8') index_lines.append(f"- [{label}]({filename}) — {etype}\n") ``` ### Technical Analysis `to_kebab()` is not injective: multiple distinct labels normalize to the same filename. For example, `A B`, `A-B`, `A_B`, and `a@b` can all become `a-b.md`. Empty or entirely non-alphanumeric labels also collapse to `entity.md`. When two entities map to the same content directory and normalized filename, `Path.write_text()` truncates and replaces the existing file. No collision check, unique suffix, or fail-safe behavior is present. The metadata remains inconsistent after an o ...[truncated 1377 chars]
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The primary purpose broadly matches: this script converts an ontology graph export into an ExpertPack-like directory structure. However, several material claims in the description are not reflected in the code. Most notably, the description explicitly says output includes YAML frontmatter on all content files, but the generated Markdown files begin with headings and contain no frontmatter. The script also does not implement richer ExpertPack features such as multi-layer retrieval or EK measurement; instead it creates a basic export and tells the user to run chunker and EK evaluator later. While schema.yaml is declared as an optional input, the loaded schema is not used in any meaningful transformation. There are no signs of unrelated malicious behavior or extra resource access, but the description overstates the implemented capabilities enough to constitute a mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs the user to read from a graph file and write a generated ExpertPack to disk, but it declares no explicit tool scope or permissions. That mismatch reduces transparency and weakens least-privilege controls, making it easier for a skill with filesystem access to be run in contexts where users or orchestrators do not realize it can modify local files.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill description says the output is 'Obsidian-compatible — includes YAML frontmatter on all content files,' but the converter writes entity markdown files beginning directly with a Markdown heading and never emits any frontmatter block. This is a semantic mismatch between the advertised export format and the actual generated files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This code creates directories and writes several files under the user-supplied output directory, including markdown, YAML, and index files. Although it prints progress messages, there is no user-facing disclosure that existing contents may be created or overwritten, and no confirmation or cautionary comment/docstring describing that behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest says the converter uses the Ontology skill's graph.jsonl and optionally schema.yaml, and the module docstring says it converts 'graph.jsonl + schema.yaml' into an ExpertPack. In code, schema.yaml is loaded but never consulted when building directories, metadata, relations, or content, so the described conversion behavior overstates what the implementation does.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.