Back to skill

Security audit

limitless-lifelogs

Security checks for vulnerabilities and agentic risk

Overview

This skill can search Limitless life logs, but it needs review because it can also send private transcript excerpts to configurable webhooks or email with incomplete safeguards.

Review this skill carefully before installing. It is suitable only if you are comfortable giving it access to Limitless lifelog transcripts and manually controlling any dispatches. Do not use dispatch until the roster path is fixed, destinations are verified, and outbound payloads are minimized or previewed with exact URLs or email recipients.

Vulnerability Patterns
  • 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
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:156
Finding
Shell Command Injection Through Transcript-Derived Webhook Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 156-169 **Vulnerability Type**: Unsafe shell interpolation and JSON construction **Risk Level**: High ### Vulnerable Code ```markdown - **webhook**: POST to `dispatch.url` with JSON body: ```json { "agent": "<name>", "task": "<task summary>", "source_quote": "<exact quote>", "log_id": "<log ID>", "timestamp": "<ISO timestamp>" } ``` ```bash curl -s -X POST -H "Content-Type: application/json" \ -d '{"agent":"NAME","task":"TASK","source_quote":"QUOTE","log_id":"ID","timestamp":"TS"}' \ "DISPATCH_URL" ``` ``` ### Technical Analysis The documented command inserts transcript-derived values such as `TASK` and `QUOTE` into a single-quoted shell argument without defining any shell-safe or JSON-safe encoding procedure. These values originate from lifelog transcripts and must therefore be treated as untrusted input. A transcript containing a single quote can terminate the `-d` argument. If the generated value also contains shell syntax, the remaining text may be interpreted as a command when an agent materializes and executes this template. Even where command execution is not achieved, quotes, backslashes, control characters, and newlines can corrupt the JSON document or modify its structure. User approval of a dispatch does not neutralize this vulnerability because the user is not instructed to inspect the generated shell command or recognize shell metacharacters in transcript content. ### Attack Path 1. An attacker speaks near the pendant or otherwise causes a crafted phrase to appear in a lifelog transcript. 2. The phrase addresses a configured agent and resembles an actionable directive, causing it to be extracted as an action item. 3. The Skill places the transcript-derived task and exact quote into the webhook dispatch template. 4. The user approves the apparently legitimate task dispatch. 5. The agent substitutes the untrusted values into the do ...[truncated 768 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct shell commands by interpolating transcript content. - Generate JSON with a structured encoder, for example: ```bash payload="$(jq -n \ --arg agent "$agent" \ --arg task "$task" \ --arg source_quote "$source_quote" \ --arg log_id "$log_id" \ --arg timestamp "$timestamp" \ '{agent:$agent, task:$task, source_quote:$source_quote, log_id:$log_id, timestamp:$timestamp}')" curl --fail-with-body --silent --show-error \ -H "Content-Type: application/json" \ --data-binary "$payload" \ "$dispatch_url" ``` - Prefer a non-shell HTTP client using a native JSON serializer. - Pass data as arguments or environment values rather than generating executable shell source. - Validate destination URLs and allow only approved `https` hosts. - Display the exact destination and encoded payload before requesting final user approval. - Add tests covering single quotes, double quotes, backslashes, newlines, command substitutions, and shell metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:171
Finding
Unsafe Shell Construction in Email Dispatch<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 171-176 **Vulnerability Type**: Shell injection and argument injection **Risk Level**: High ### Vulnerable Code ```markdown - **email**: Inform the user what the email should contain and ask them to send it, or use the system `mail` command if available: ```bash echo "Task for AGENT_NAME:\nTASK_SUMMARY\n\nSource: QUOTE\nLog: LOG_ID" | \ mail -s "Task from Limitless" AGENT_EMAIL ``` ``` ### Technical Analysis The email command is presented as a shell template containing transcript-derived fields such as `TASK_SUMMARY` and `QUOTE`. It does not prescribe safe handling when these placeholders are replaced with actual values. If an implementation generates shell source through direct textual replacement, shell metacharacters or command substitutions in transcript content can be evaluated. The `AGENT_EMAIL` value is also unquoted. A malicious or malformed roster value can therefore be interpreted as multiple shell words or as command-line options by `mail`. An address beginning with `-` may be treated as an option rather than a recipient. The use of `echo` is additionally non-portable for escape handling and is unsuitable as a robust serialization mechanism for untrusted message content. ### Attack Path 1. An attacker causes crafted task text or a crafted exact quote to appear in a recorded transcript, or modifies an accessible roster email value. 2. The Skill identifies the phrase as an action item and offers email dispatch. 3. The user approves the dispatch. 4. The agent substitutes the untrusted values directly into the documented command. 5. The shell evaluates injected syntax, or `mail` interprets the unquoted recipient as additional options or recipients. 6. Commands may execute with the OpenClaw user's privileges, or sensitive content may be delivered to unintended recipients. ### Impact Assessment Depending on how the command template is materialized, exploitation may ...[truncated 377 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid generating shell commands containing transcript or roster values. - Use a mail API or library that accepts the recipient, subject, and body as distinct data fields. - If the system `mail` utility must be used: - Validate the recipient against a strict email-address policy. - Reject recipient values beginning with `-`. - Permit only one explicitly configured recipient unless multiple recipients are a documented requirement. - Quote every shell argument. - Store the body in a securely created file or pass literal data through standard input without evaluating it as shell source. - Use an end-of-options delimiter where supported. - Replace `echo` with a predictable data-writing mechanism such as `printf '%s'`. - Show the exact recipient and message fields to the user before dispatch. - Add security tests using spaces, leading hyphens, quotes, semicolons, command substitutions, and newline characters. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:151
Finding
Disclosure of Private Transcript Content to Unrestricted Dispatch Destinations<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 151-169 **Vulnerability Type**: Excessive sensitive-data disclosure and insufficient destination validation **Risk Level**: Medium ### Vulnerable Code ```markdown **Dispatch Prompt** After presenting each extracted action item, ask the user: > "Should I dispatch this task to [Agent Name]?" If the user says yes, read the agent's `dispatch` config from `agents.json` and use the appropriate method: - **webhook**: POST to `dispatch.url` with JSON body: ```json { "agent": "<name>", "task": "<task summary>", "source_quote": "<exact quote>", "log_id": "<log ID>", "timestamp": "<ISO timestamp>" } ``` ```bash curl -s -X POST -H "Content-Type: application/json" \ -d '{"agent":"NAME","task":"TASK","source_quote":"QUOTE","log_id":"ID","timestamp":"TS"}' \ "DISPATCH_URL" ``` ``` ### Technical Analysis The dispatch payload includes an exact quote from a private pendant transcript, a task summary, a log identifier, and a timestamp. The destination comes from `dispatch.url`, but the Skill defines no HTTPS requirement, hostname allowlist, trust verification, redaction policy, or destination preview. Dispatch is part of the declared functionality and requires user confirmation. However, the confirmation prompt identifies only the agent name. It does not require disclosure of the destination URL or the complete set of sensitive fields that will be sent. Transmitting the exact source quote is not generally required to dispatch a summarized task and therefore exceeds the minimum data necessary for the core operation. Exact quotes can contain private conversations, names, health information, credentials spoken aloud, business information, or information about third parties who did not consent to external disclosure. ### Attack Path 1. A malicious, compromised, or mistakenly configured `agents.json` entry specifies an external webhook. 2. The Skill retrieves pri ...[truncated 1096 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Apply data minimization: send only the task summary and agent name by default. - Make transmission of exact transcript quotes, log IDs, and timestamps separately opt-in. - Before dispatch, display: - The exact destination URL or email address. - Every field that will be transmitted. - Whether an exact transcript quote is included. - Require a second explicit confirmation after this preview. - Restrict webhook destinations to `https` URLs and an administrator- or user-maintained hostname allowlist. - Reject URLs containing embedded credentials, unexpected ports, redirects to unapproved hosts, or local/private-network destinations unless specifically required. - Provide redaction controls for names, credentials, health data, and other sensitive content. - Document retention and trust assumptions for external agents. - Record a local audit event containing the approved destination and field names without unnecessarily duplicating transcript content. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
install.sh:5
Finding
Installer and Runtime Roster Path Mismatch Can Select an Unintended Dispatch Configuration<![CDATA[ ## Vulnerability Details **File Location**: `install.sh`, lines 5-18; `SKILL.md`, lines 123, 181, and 194 **Vulnerability Type**: Inconsistent security-sensitive configuration path **Risk Level**: Medium ### Vulnerable Code `install.sh` installs and preserves the roster under `limitless_lifelogs`: ```bash set -e SKILL_NAME="limitless_lifelogs" SKILL_DIR="$HOME/.openclaw/workspace/skills/$SKILL_NAME" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "Installing $SKILL_NAME skill to $SKILL_DIR ..." mkdir -p "$SKILL_DIR" # Copy skill files cp "$SCRIPT_DIR/SKILL.md" "$SKILL_DIR/SKILL.md" # Copy agents.json only if it doesn't already exist (preserve user edits) if [ ! -f "$SKILL_DIR/agents.json" ]; then cp "$SCRIPT_DIR/agents.json" "$SKILL_DIR/agents.json" ``` `SKILL.md` instead reads and references a roster under `limitless`: ```bash cat ~/.openclaw/workspace/skills/limitless/agents.json | jq '[.agents[].name]' ``` ```markdown > to `~/.openclaw/workspace/skills/limitless/agents.json` to enable dispatch. ``` ```markdown | `agents.json` missing | "agents.json not found. Create it at `~/.openclaw/workspace/skills/limitless/agents.json` using the template in the skill repo." | ``` ### Technical Analysis The installer places the Skill and its roster in: ```text ~/.openclaw/workspace/skills/limitless_lifelogs/ ``` The runtime instructions direct the agent to read: ```text ~/.openclaw/workspace/skills/limitless/ ``` As a result, the roster installed or reviewed by the user may not be the roster used at runtime. If the alternate directory already exists, its agent names and dispatch destinations may silently control task dispatch. This is security-sensitive because roster entries determine where transcript-derived information is sent. The mismatch can also cause ordinary failures when the alternate file does not exist, but its security consequence is recipient substitution when an unexpected file is present. ### Attack Path 1. ...[truncated 1151 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Use one canonical Skill directory consistently. For example, replace every reference to: ```text ~/.openclaw/workspace/skills/limitless/agents.json ``` with: ```text ~/.openclaw/workspace/skills/limitless_lifelogs/agents.json ``` - Prefer deriving the roster location from the loaded Skill directory rather than hardcoding a home-relative path. - Resolve the path canonically and reject symbolic links or unexpected path traversal where the platform permits. - Check that the roster is owned by the expected user and is not writable by other users. - Validate `agents.json` against a strict schema before use. - Display the resolved roster path and selected destination during dispatch confirmation. - Add an installation self-test that verifies the installed path matches all paths referenced by `SKILL.md`. - Fail closed if multiple candidate roster files exist rather than silently selecting one. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The skill explicitly claims to be read-only, yet later instructs the agent to send POST requests and optionally invoke the local mail command. This contradiction can mislead reviewers and users into approving a skill that performs outbound side effects and shares sensitive life-log content.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The documentation contains an internal contradiction: it labels the skill read-only while also directing task dispatch through webhook POSTs and email. Such mismatches obscure the real security posture of the skill and make sensitive outbound data transfer more likely to be overlooked during review or use.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest frames the skill as a life-log search and summarization tool, but the documented behavior expands into operational task dispatch via webhooks and local email. This is a capability escalation from passive analysis to active exfiltration/action, which can cause sensitive transcript content to be sent to external systems under the guise of summarization.

Missing User Warnings

High
Confidence
99% confidence
Finding
The dispatch flow instructs the agent to send extracted tasks, exact source quotes, log IDs, and timestamps to webhooks or email without a clear user-facing warning that sensitive transcript content is leaving the system. Given the personal nature of life logs, this creates a substantial privacy and confidentiality risk.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
Invoking the system mail command is an active outbound capability that is unnecessary for core search/summarization and can transmit sensitive transcript-derived content outside the platform. It also relies on local system tooling, creating additional attack surface and policy bypass risk compared with keeping all actions in-chat.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This skill operates on highly sensitive life-log recordings but does not provide a prominent privacy warning before access and analysis. Users may not understand that the skill can search and synthesize intimate recorded conversations, which raises consent and expectation risks.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -s -H "X-API-Key: $LIMITLESS_API_KEY" \
  "https://api.limitless.ai/v1/lifelogs?timezone=$LIMITLESS_TIMEZONE&PARAMS"
```

Query parameters (append as `&key=value`):
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
curl -s -H "X-API-Key: $LIMITLESS_API_KEY" \
  "https://api.limitless.ai/v1/lifelogs?timezone=$LIMITLESS_TIMEZONE&PARAMS"
```

Query parameters (append as `&key=value`):
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
Reading a local roster file introduces access to workspace-local configuration unrelated to simple life-log retrieval, and then uses that data to drive external dispatch behavior. This broadens the skill's trust boundary from API-only log access to local file ingestion and action routing, increasing the chance of misuse or unintended data flow.

External Transmission

Medium
Category
Data Exfiltration
Content
}
  ```
  ```bash
  curl -s -X POST -H "Content-Type: application/json" \
    -d '{"agent":"NAME","task":"TASK","source_quote":"QUOTE","log_id":"ID","timestamp":"TS"}' \
    "DISPATCH_URL"
  ```
Confidence
93% confidence
Finding
The webhook POST transmits transcript-derived task data, including source quotes and metadata, to an external URL. Even if intended for legitimate integration, this is a real data egress path that could expose sensitive life-log content to third parties or misconfigured endpoints.

Session Persistence

Medium
Category
Rogue Agent
Content
| HTTP 429 | "Rate limit hit (180 req/min). Wait 60 seconds and try again." |
| HTTP 404 | "That log ID wasn't found. It may have been deleted or the ID is incorrect." |
| Empty results | "No logs found matching that query. Try a broader search term or different date range." |
| `agents.json` missing | "agents.json not found. Create it at `~/.openclaw/workspace/skills/limitless/agents.json` using the template in the skill repo." |
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrase "Obi" is a common standalone name and is likely to appear in ordinary conversation, quoted text, or discussion about the agent rather than as an intentional invocation. In a life-logging/search skill, accidental activation can cause unintended dispatches to the configured webhook, which may expose sensitive personal context or trigger actions when the user did not mean to invoke the agent.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "Installing $SKILL_NAME skill to $SKILL_DIR ..."

mkdir -p "$SKILL_DIR"

# Copy skill files
cp "$SCRIPT_DIR/SKILL.md" "$SKILL_DIR/SKILL.md"
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
echo ""
echo "  1. Set your API key:"
echo "       export LIMITLESS_API_KEY=your_key_here"
echo "       # Add to ~/.zshrc or ~/.bashrc to persist it."
echo ""
echo "  2. Set your timezone (optional, defaults to UTC):"
echo "       export LIMITLESS_TIMEZONE=America/Los_Angeles"
Confidence
90% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Static analysis

No suspicious patterns detected.