Back to skill

Security audit

TELOS

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent personal-context purpose, but it handles very sensitive local life data with broad automatic loading, persistent hook injection, and unsafe restore/update paths that warrant review before installation.

Install only if you are comfortable storing sensitive personal material locally and having it read by your AI assistant. Avoid installing the optional hook until it has stricter consent, lower-trust context injection, and clearer audit controls. Do not run restore commands with arbitrary names or paths, and avoid recording secrets, explicit trauma details, or third-party text without careful review.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/backup-telos.ts:88
Finding
Unvalidated Backup and Restore Paths Permit Arbitrary Filesystem Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/backup-telos.ts:66-67, 88-108, 169-187` **Vulnerability Type**: Path traversal and unrestricted filesystem copy/overwrite **Risk Level**: High ### Vulnerable Code ```ts const timestamp = getTimestamp(); const name = customName ? `${SNAPSHOT_PREFIX}${customName}-${timestamp}` : `${SNAPSHOT_PREFIX}${timestamp}`; const snapshotPath = join(SNAPSHOTS_DIR, name); ``` ```ts function cmdRestore(snapshotName: string) { const snapshotPath = snapshotName.startsWith("/") ? snapshotName : join(SNAPSHOTS_DIR, snapshotName.startsWith(SNAPSHOT_PREFIX) ? snapshotName : `${SNAPSHOT_PREFIX}${snapshotName}`); if (!existsSync(snapshotPath)) { console.error(`Snapshot not found: ${snapshotPath}`); cmdList(); process.exit(1); } // Safety: backup current state before restoring if (existsSync(TELOS_DIR)) { const safetyName = `${SNAPSHOT_PREFIX}pre-restore-${getTimestamp()}`; const safetyPath = join(SNAPSHOTS_DIR, safetyName); mkdirSync(SNAPSHOTS_DIR, { recursive: true }); cpSync(TELOS_DIR, safetyPath, { recursive: true }); console.log(`Safety snapshot created: ${safetyName}`); } // Restore rmSync(TELOS_DIR, { recursive: true, force: true }); cpSync(snapshotPath, TELOS_DIR, { recursive: true }); console.log(`\nRestored from: ${basename(snapshotPath)}`); console.log(`Location: ${TELOS_DIR}`); } ``` ```ts function cmdRestoreFile(filename: string, version: string) { const backupPath = join(BACKUPS_DIR, version); if (!existsSync(backupPath)) { console.error(`Backup not found: ${backupPath}`); cmdHistory(filename); process.exit(1); } const targetPath = join(TELOS_DIR, filename); // Backup current version before restoring if (existsSync(targetPath)) { mkdirSync(BACKUPS_DIR, { recursive: true }); const timestamp = getTimestamp(); const safetyBackup = `${filename.replace(".md", "")}_pre-restore_${timestamp}.md`; cpSync(targ ...[truncated 2322 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject absolute paths and all arguments containing path separators, `.` segments, or `..` segments. 2. Restrict snapshot names to a conservative pattern such as: ```ts const SAFE_SNAPSHOT = /^telos-snapshot-[A-Za-z0-9_-]+$/; ``` 3. Allowlist `filename` against the same fixed TELOS filename list used by `update-telos.ts`. 4. Resolve and verify every path before accessing it: ```ts import { resolve, relative, isAbsolute } from "path"; function resolveWithin(parent: string, child: string): string { if (isAbsolute(child)) throw new Error("Absolute paths are not allowed"); const base = resolve(parent); const candidate = resolve(base, child); const rel = relative(base, candidate); if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) { throw new Error("Path escapes the allowed directory"); } return candidate; } ``` 5. Verify that a full-restore source is a directory and conforms to the expected snapshot structure. 6. Verify that a file-restore source is a regular Markdown file, not a directory or symbolic link. 7. Consider rejecting symbolic links throughout snapshot creation and restoration. 8. Stage restored data in a temporary directory, validate it, and use an atomic rename instead of deleting the live directory first. 9. Require explicit user confirmation that displays the canonical source and destination before any destructive restore. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
"<content>" "<description>"` 3. **Confirm briefly** — Mention it's backed up and logged. Don't dump execution logs. 4. **Suggest connections** — After adding to one file, suggest related files that might benefit. ("This connects to your B0 about compounding — want to add a related strategy?") ``` ```md ## Update Command Use the TypeScript update script for all changes: ```bash bun <skill-dir>/scripts/update-telos.ts <file> "<content>" "<change-description>" ``` ``` ### Technical Analysis The skill inst ...[truncated 1968 chars]:102
Finding
User-Controlled TELOS Content Is Interpolated into Shell Commands<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:102-108`; `references/update-workflow.md:5-9` **Vulnerability Type**: Shell command injection through unsafe command construction **Risk Level**: High ### Vulnerable Code ```md 1. **Engage first** — Acknowledge what the user shared. Reflect on the insight, ask a follow-up, or connect it to their existing telos context. This is a life framework, not a database — treat additions as meaningful moments. 2. **Execute** — Run the update script: `bun {baseDir}/scripts/update-telos.ts <file> "<content>" "<description>"` 3. **Confirm briefly** — Mention it's backed up and logged. Don't dump execution logs. 4. **Suggest connections** — After adding to one file, suggest related files that might benefit. ("This connects to your B0 about compounding — want to add a related strategy?") ``` ```md ## Update Command Use the TypeScript update script for all changes: ```bash bun <skill-dir>/scripts/update-telos.ts <file> "<content>" "<change-description>" ``` ``` ### Technical Analysis The skill instructs the agent to place conversation-derived content and descriptions directly inside a textual shell command. Double quotes do not safely neutralize all shell syntax. Embedded quotation marks can terminate the intended argument, while command substitutions and other metacharacters may still be interpreted by a shell. The TypeScript update script itself consumes `process.argv` and does not invoke a shell. The vulnerability occurs at the documented invocation boundary: if the agent follows the instructions by constructing and executing a shell command string, untrusted content can alter the command. The risk applies to ordinary update requests and the batch extraction workflow, where potentially untrusted text copied from a conversation or interview is converted into command arguments. ### Attack Path 1. An attacker supplies TELOS content containing shell-significant syntax, embedded quotation marks, or comman ...[truncated 933 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prohibit shell-string construction for updates. 2. Invoke Bun through a structured process API with a literal argument array and shell execution disabled: ```ts spawn("bun", [scriptPath, filename, content, description], { shell: false, stdio: "inherit", }); ``` 3. Prefer accepting update data through standard input or a securely created JSON file: ```bash printf '%s' "$JSON_DATA" | bun update-telos.ts --stdin ``` The agent must still use a structured tool interface rather than interpolate data into `printf`. 4. Update `SKILL.md` and `references/update-workflow.md` to explicitly require a no-shell tool call with separate arguments. 5. If the platform only exposes a shell, write content to a securely created file through a non-shell API and pass only its validated path. 6. Add adversarial tests covering embedded quotes, command substitutions, newlines, semicolons, and redirection characters. 7. Continue allowlisting the target filename, but do not treat filename validation as protection for the separate content and description arguments. ]]>

T02 · Agent Memory Poisoning

Error
Location
hooks/telos-context.js:99
Finding
Persisted User Content Is Reintroduced as Trusted System-Role Instructions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/update-telos.ts:92-96`; `hooks/telos-context.js:53-60, 99-109, 115-132`; `references/update-workflow.md:48-52` **Vulnerability Type**: Persistent prompt injection and agent memory poisoning **Risk Level**: High ### Vulnerable Code ```ts // 2. Append content (never overwrite) try { const current = readFileSync(targetFile, "utf-8"); writeFileSync(targetFile, current.trimEnd() + "\n\n" + content + "\n", "utf-8"); console.log(`Updated: ${filename}`); } catch (error) { console.error(`Failed to update: ${error}`); process.exit(1); } ``` ```js function readTelosFile(filename) { const filepath = path.join(TELOS_DIR, filename); if (!fs.existsSync(filepath)) return null; const content = fs.readFileSync(filepath, "utf-8"); // Skip if only template content (less than 200 chars of real content) if (content.replace(/^#.*$/gm, "").replace(/\[.*?\]/g, "").trim().length < 50) return null; return content; } ``` ```js if (context.length > 0) { ctx.inject = ctx.inject || []; ctx.inject.push({ role: "system", content: `[TELOS Context — User's life framework]\n\n${context.join("\n\n")}`, }); } ``` ```js const topics = detectTopics(ctx.message.content); if (topics.length === 0) return; const files = getFilesForTopics(topics); const context = []; for (const file of files) { const content = readTelosFile(file); if (content) context.push(`--- ${file} ---\n${content}`); } if (context.length > 0) { ctx.inject = ctx.inject || []; ctx.inject.push({ role: "system", content: `[TELOS Context — Relevant to this question]\n\n${context.join("\n\n")}`, }); } ``` ```md ## Batch Interview Extraction When the user says "extract from this conversation/interview into telos": 1. Identify all telos-relevant content (beliefs, lessons, books, goals, challenges) 2. Group by file type 3. Run update script once per file 4. Report summary: "Added 2 beliefs, 1 book, 3 lessons" ``` ### ...[truncated 2282 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not inject mutable TELOS records as system-role messages. Supply them through a lower-trust data channel supported by the host platform. 2. Add an explicit instruction boundary stating that TELOS text is untrusted reference data and that directives found inside it must never be executed. 3. Replace free-form Markdown ingestion with a strict structured schema containing fields such as identifier, statement, evidence, date, and provenance. 4. Reject or quarantine entries containing agent-control language, tool instructions, role markers, hidden text, or requests to override prior instructions. 5. Require explicit confirmation before persisting content extracted from third-party conversations or documents. 6. Record provenance for every entry, distinguishing direct user statements from imported or model-inferred content. 7. Present the exact normalized content to the user before it becomes eligible for automatic context loading. 8. Apply output encoding and robust delimiters when serializing data into model context; do not rely on Markdown headings alone. 9. Limit bootstrap loading to validated structured fields and exclude raw free-form bodies. 10. Provide a command to review, disable, and remove the hook and to inspect all content scheduled for automatic injection. 11. Add tests containing prompt-injection phrases in every TELOS file and verify that they remain inert data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (26)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code's actual primary behavior is contextual reading and injection of TELOS markdown files into OpenClaw sessions. It loads core files at bootstrap and additional files when message text matches predefined keywords/topics. There are no file write operations, backup creation, restore logic, snapshot listing, or onboarding flows. The storage location is also not the declared ~/clawd/telos/ path; instead it resolves from OPENCLAW_WORKSPACE or CLAWD_WORKSPACE and defaults to ~/openclaw/telos. While the code does support using TELOS as context for personal questions, the declared description materially overstates capabilities and specifies inconsistent resources, so this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code chunk only implements backup-oriented filesystem operations over the TELOS directory tree: snapshot creation, snapshot listing, full restore, file backup history inspection, and single-file restore. While these actions partially align with the declared backup/restore/history aspects, the declared description is much broader and centers on a personal life OS assistant that reads, updates, and supplies TELOS context for life decisions. None of that contextual-assistant behavior appears in this code. The resource path is also not strictly limited to ~/clawd/telos/ as declared; it prefers OPENCLAW_WORKSPACE or CLAWD_WORKSPACE and defaults to ~/openclaw/telos, with ~/clawd/telos only mentioned in comments/usage as legacy. This is a meaningful description-behavior mismatch because the actual code is a narrow backup/restore utility rather than the full TELOS management and advisory capability described.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The description presents a full-featured TELOS management skill covering read/update/backup/restore/history capabilities and life-aligned context retrieval. The actual code chunk only initializes the TELOS folder structure and starter files from templates. While creating the backups directory and an updates log is consistent with setup, the implemented behavior is materially narrower than the declared purpose. This is a description-to-code mismatch because the code does not implement most of the stated capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The description claims a multi-function TELOS system for reading, updating, backing up, restoring, and surfacing personal missions/goals/beliefs as context for AI assistance. The actual code only performs one narrow operation: append content to a specific allowed markdown file, make a backup copy first, and log the change. That is consistent with part of the declared update/backup functionality, but it does not cover several prominently declared capabilities such as reading telos data, restoring backups, listing snapshot history, or providing telos context for decision support. Additionally, the filesystem location is broader/different than described because it resolves via environment variables or ~/openclaw/telos, with ~/clawd/telos only mentioned as legacy in comments. This is a material description-behavior mismatch for the supplied code chunk.

Vague Triggers

High
Confidence
95% confidence
Finding
The skill is configured to trigger not only on explicit 'telos' commands but also on broad personal-topic categories like career, investments, relationships, priorities, and life strategy. In context, that means sensitive TELOS content may be pulled into many ordinary conversations without a narrowly scoped user request, increasing the risk of privacy over-collection, oversharing, and prompt-context exposure of intimate personal data.

Vague Triggers

High
Confidence
95% confidence
Finding
The optional hook provides persistent automatic injection at session start and per-message based on broad keyword/topic detection, including core files like MISSION, GOALS, and BELIEFS. Persistent preloading of deeply personal context into the system prompt materially raises the risk of unnecessary exposure across sessions, accidental inclusion in unrelated responses, and expansion of the blast radius if other prompt-handling components are compromised.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README states that the AI automatically reads TELOS at session start and injects relevant personal files into responses, but it does not present a strong, front-and-center warning that this behavior accesses sensitive local data. In this skill’s context, the data includes beliefs, traumas, challenges, and other intimate information, so insufficient disclosure raises the risk of users unknowingly exposing or over-sharing private context to the model or downstream tooling.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger examples are broad enough to cause the skill to activate for common personal-advice topics such as career, relationships, priorities, or investments, even when the user did not explicitly request TELOS access. In this skill’s context, unintended invocation matters because activation can lead to reading highly sensitive local files and shaping responses with private data without a narrowly scoped user intent signal.

Lp3

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding
The skill instructs the agent to read environment-controlled paths such as $OPENCLAW_WORKSPACE and to copy/install a hook into ~/.openclaw/hooks, but it declares no explicit tool scope or permissions boundary. In a skill that handles sensitive personal data and persistent hook installation, the absence of declared capabilities increases the chance of overbroad file/environment access and makes security review and runtime restriction weaker.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill metadata says TELOS lives in ~/clawd/telos/, while the body says $OPENCLAW_WORKSPACE/telos/ with a fallback to ~/openclaw/telos/. For a skill handling highly sensitive personal beliefs, goals, traumas, and history, path confusion can cause the agent or user to read from, write to, back up, or restore the wrong directory, leading to accidental disclosure, integrity loss, or missed protection assumptions.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The documentation contradicts itself about where TELOS data is stored and when files should be loaded. In a skill designed to silently absorb private life data, inconsistent instructions increase the chance of unintended data access, accidental persistence in the wrong location, or use of stale/incorrect personal context in decision support.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The on-demand loading rules tell the agent to infer relevance from loosely defined life dimensions and to 'absorb silently' without announcing reads. Ambiguous topical matching combined with silent access makes it difficult for users to understand when highly sensitive files, including beliefs or traumas, are being consulted, which undermines consent and least-privilege handling of personal data.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The template explicitly asks users to record formative traumas, beliefs, goals, and other deeply sensitive personal information, but provides no privacy, retention, access-control, or data-handling warning. In the context of a skill that stores this material under a local path for ongoing AI assistance and backups, this increases the risk of oversharing, unauthorized disclosure, secondary use, or accidental inclusion in model context.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This template explicitly prompts the user to document highly sensitive mental health and trauma history, including formative experiences, resulting patterns, and processing status, but provides only a vague 'private' note rather than concrete warnings about sensitivity, storage risk, access controls, or when not to record such details. In the context of a skill that reads, updates, and backs up a personal life OS in a filesystem directory, this creates a real privacy and safety risk because deeply sensitive material may be stored persistently, copied into backups, or surfaced in AI context without informed consent or minimization.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The expected behavior explicitly instructs the agent to run an update script, modify BOOKS.md, create a backup, and log a change without mentioning any confirmation, preview, or user consent flow. In a skill that operates on personal files under the user's home directory, silent writes increase the risk of unintended modification, over-collection, or persistence of sensitive personal information.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The eval expects the skill to inspect ~/clawd/telos/ for personal goals, beliefs, and mission data before advising the user, but it does not require any privacy notice, consent, or data-minimization step. Because TELOS is explicitly a personal life-OS containing highly sensitive context, implicit access to that directory can expose intimate data and normalize unnecessary reads of private material.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The hook resolves TELOS data from a generic workspace-controlled path instead of the manifest-described fixed location. If the workspace environment variable is changed or points to a shared/untrusted directory, the hook may ingest the wrong user's personal files or attacker-controlled content into system context, causing privacy leakage or prompt-context poisoning.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The hook automatically injects personal TELOS files into system context when message text matches broad keywords like 'career', 'life', or 'what should i do', without explicit per-message consent or visible disclosure. This can expose highly sensitive personal information to sessions where the user did not intend TELOS retrieval, and because injection occurs as system content, it can also amplify the impact of any malicious or manipulative text stored in those files.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrase is broad enough that ordinary conversation about filling out personal planning materials could invoke the skill unexpectedly. Because this skill reads and writes persistent personal data under the user's home directory, accidental activation can cause unintended collection, storage, or modification of sensitive life-planning information.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The onboarding flow directs immediate creation of directories and files in ~/clawd/telos/ and overwrites updates.md without first informing the user or obtaining consent. Silent local file modification is risky because it can destroy prior data, create persistent artifacts the user did not expect, and normalize filesystem access for a skill handling sensitive personal information.

Ssd 3

Medium
Confidence
91% confidence
Finding
The skill encourages ongoing inference and persistence of personal goals and beliefs from natural conversations over time, which expands data collection beyond a single explicit onboarding action. In the context of a life-operating-system skill, this creates meaningful privacy risk because highly sensitive psychological, relational, career, and belief information may be stored or suggested for storage without clear session-by-session consent boundaries.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The workflow instructs the agent to make persistent local updates, backups, and logs in the user's home directory without any warning, consent checkpoint, or visibility requirement. Because TELOS stores highly personal life-planning data, silent persistence increases the chance of unintended disclosure, retention of sensitive information, and user surprise about local state changes.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The trigger phrase for batch extraction is broad enough that ordinary user discussion about a conversation or interview could activate persistent writes into the user's TELOS store without sufficiently explicit confirmation. In this skill, that risk is amplified because the workflow performs real local file updates and backups, so a misfire can silently create durable, privacy-sensitive records from conversational content.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The restore command explicitly accepts any absolute path as a snapshot source, bypassing the intended restriction to the dedicated Telos snapshots directory. An attacker or unsafe caller that can influence the restore argument could cause the tool to recursively copy arbitrary filesystem content into the Telos directory after first deleting the current state, resulting in integrity loss and possible exposure or planting of unexpected data.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The restore-file command joins unvalidated user-controlled filename input with TELOS_DIR, so path traversal strings such as '../' or absolute-style variants can target files outside the intended Telos file set. Because the command writes restored content to that computed path and also creates a backup based on the supplied filename, an attacker could overwrite arbitrary files reachable from the workspace context.

Static analysis

No suspicious patterns detected.