Back to skill

Security audit

Excretion Tracker

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent bathroom tracker, but it needs review because it stores sensitive health data and gives unsafe command templates for user-provided text.

Review before installing, especially on a shared machine. This skill records private bathroom and symptom details in a local plaintext database and may create image files with those details if cards are enabled. Use it only if you are comfortable with that local persistence, and prefer a version that enforces private file permissions, documents deletion and retention, and invokes the CLI without shell interpolation.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:100
Finding
Shell Command Injection Through User-Controlled CLI Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 100–106 **Vulnerability Type**: Command injection through unsafe shell interpolation **Risk Level**: High ### Vulnerable Code ```markdown - Log pee: - `excretion log pee --start-at "..." --duration-sec 60 --color yellow --pain 0 --notes "..."` - Log poop: - `excretion log poop --start-at "..." --duration-sec 180 --color normal_brown --pain 1 --bristol 4 --notes "..."` ``` ### Technical Analysis The skill directs the Agent to construct CLI commands containing values derived from chat input, including `--start-at` and `--notes`. The instructions do not require structured process invocation, argument arrays, or shell-safe escaping. Wrapping a value in double quotes does not prevent shell evaluation. Shell substitutions such as `$(command)` and backtick expressions remain active inside double-quoted strings. If the Agent builds and executes the documented command through a shell, an attacker can place shell syntax in a note or another interpolated field. For example, a note containing the following value would remain executable if directly inserted into the documented template: ```text $(touch /tmp/excretion-command-injection) ``` The resulting command could resemble: ```bash excretion log pee --start-at "2026-03-01 10:10" \ --duration-sec 60 --color yellow --pain 0 \ --notes "$(touch /tmp/excretion-command-injection)" ``` The shell evaluates the command substitution before invoking the tracker. The Python CLI itself uses parameterized SQL and does not cause this issue; the vulnerability exists in the Agent-facing command-construction instructions. ### Attack Path 1. An attacker or untrusted user asks the Agent to log a bathroom event. 2. The attacker supplies a required or optional textual field containing shell metacharacters, such as a note with `$(command)`. 3. The Agent follows `SKILL.md` and interpolates the supplied value into the documented shell command. 4. The Agen ...[truncated 869 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never construct a shell command by concatenating or interpolating user-controlled values. - Invoke the CLI through a structured argument array with shell processing disabled. For example: ```python subprocess.run( [ "python3", "scripts/excretion.py", "log", "pee", "--start-at", start_at, "--duration-sec", str(duration_sec), "--color", color, "--pain", str(pain), "--notes", notes, ], check=True, shell=False, ) ``` - Update `SKILL.md` to explicitly prohibit execution through `sh -c`, `bash -c`, or equivalent shell wrappers. - Treat every chat-derived value as untrusted, including timestamps, notes, colors, durations, and generated filenames. - Validate values against strict formats and length limits before invocation. - If shell invocation is unavoidable, use a well-tested platform-specific quoting mechanism for every untrusted argument; structured invocation should remain the preferred solution. - Add tests using payloads containing `$()`, backticks, quotes, semicolons, newlines, pipes, and redirection operators. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/excretion.py:29
Finding
Sensitive Health Database Created Without Explicitly Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/excretion.py`, lines 29–39 **Vulnerability Type**: Insecure permissions for plaintext sensitive data **Risk Level**: Medium ### Vulnerable Code ```python def db_path() -> Path: return Path.home() / ".openclaw" / "excretion" / "excretion.db" def ensure_db_dir() -> None: db_path().parent.mkdir(parents=True, exist_ok=True) def connect() -> sqlite3.Connection: ensure_db_dir() con = sqlite3.connect(db_path()) ``` ### Technical Analysis The application stores sensitive health-related information in a local SQLite database, including bathroom-event timestamps, pain levels, blood indicators, stool form and color, and free-text notes. The database directory is created without an explicit mode, and the SQLite file's permissions are not explicitly restricted after creation. Consequently, effective permissions depend on the process umask and any pre-existing directory state. Under a permissive configuration, the directory or database may be readable by other local users or processes. SQLite data is stored in plaintext. The implementation also does not verify or correct permissions when the directory or database already exists. This creates an access-control weakness for particularly sensitive personal information. ### Attack Path 1. The skill runs under a permissive umask or uses a pre-existing directory with permissive permissions. 2. `ensure_db_dir()` creates or reuses `~/.openclaw/excretion/` without enforcing owner-only access. 3. `sqlite3.connect()` creates or opens `excretion.db` without enforcing an owner-only file mode. 4. Another local user or process with filesystem access traverses the directory. 5. The local actor reads or copies the SQLite database and extracts the health records. This attack requires local filesystem access and depends on the effective directory, file, and parent-directory permissions. ### Impact Assessment Exploitation can disclose private health and ...[truncated 407 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create the data directory with owner-only permissions: ```python directory = db_path().parent directory.mkdir(parents=True, exist_ok=True, mode=0o700) os.chmod(directory, 0o700) ``` - Create the database with an owner-only mode and verify that mode after connecting: ```python path = db_path() con = sqlite3.connect(path) os.chmod(path, 0o600) ``` - Use secure file creation semantics that avoid a race between creation and permission correction where supported. - Verify and repair permissions for existing directories and database files rather than securing only newly created resources. - Consider checking ownership and refusing to use a database or directory owned by another account. - Account for SQLite auxiliary files such as journal or WAL files and ensure the containing directory prevents unauthorized access to them. - Document that the database contains sensitive health information and define retention, deletion, backup, and export controls. - Where the threat model includes hostile local users or compromised backups, consider application-level encryption with keys stored separately from the database. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
The skill’s declared behavior does not accurately match what it instructs the agent to do, especially around collecting additional sensitive health data and using a local CLI-backed workflow. In a health-tracking context, undocumented data collection and misleading claims about reminders or interaction mode can undermine informed consent, cause unexpected retention of highly sensitive medical information, and lead users to rely on features that may not exist.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger keywords are broad enough to activate on ordinary conversation about bowel, urine, constipation, or symptoms, which risks invoking the skill when the user is seeking general discussion rather than consenting to log health events. Because the subject matter is highly sensitive medical data, accidental activation can lead to over-collection, unnecessary prompting, or unintended storage of private information.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill handles highly sensitive health information but does not provide an upfront warning in the description that these details are stored locally through CLI logging. Users may disclose intimate medical data without understanding that it will be persisted, which creates a meaningful privacy and consent failure even if storage is only local.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The instruction says to ask for missing required fields "in the user's language (Chinese)," which effectively forces Chinese output rather than detecting or offering the user's preferred language. This is a language-policy issue because the skill imposes a specific locale without opt-in or a documented region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The natural-language prompt explicitly forces Chinese text such as "厕所记录" and Chinese label translations on the generated card. This is a language/locale policy issue because the file does not offer the user a language choice or explain why Chinese output is required.

Session Persistence

Medium
Category
Rogue Agent
Content
## How to run Nano Banana Pro (example)

```bash
mkdir -p ~/.openclaw/media/excretion-cards
uv run /Users/herve.clawd/.openclaw/workspace/skills/nano-banana-pro/scripts/generate_image.py \
  --prompt "<PROMPT>" \
  --filename "$HOME/.openclaw/media/excretion-cards/excretion-card-YYYY-MM-DD-HH-MM-SS.png" \
Confidence
83% confidence
Finding
The SOP instructs creating a persistent local directory and saving generated image files containing bathroom-event metadata such as time, duration, color, pain, and Bristol scale. Because this is sensitive health-adjacent information, persistent storage can create a privacy risk if the user is not clearly informed, if files accumulate indefinitely, or if local access by other software/users is possible.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
Hard-coding DEFAULT_TZ = 'Asia/Shanghai' for sensitive health-event records can silently mislabel timestamps and distort time-based analysis such as nocturia counts, weekly windows, and interval calculations for users in other regions. In this context the issue is mainly data-integrity and privacy-context risk rather than direct compromise, but incorrect timing can still produce misleading health reminders and summaries.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The weekly summary treats every non-pee event as poop, so 'attempt' events are counted as bowel movements and included in poop pain/interval statistics. In a health-tracking skill, this creates materially incorrect summaries that can mislead users about constipation, bowel frequency, and symptom trends, which is a real integrity issue even though it is not code-execution related.

Missing User Warnings

Low
Confidence
79% confidence
Finding
This markdown file instructs the skill to produce a PNG in a local directory and later shows commands that create that directory and write an output file. Under the markdown-file criteria for missing user warnings, there is no explicit warning that the skill may create local files or invoke an installed external generator to process user-provided event data.

Intent-Code Divergence

Low
Confidence
90% confidence
Finding
The top-level docstring presents the tool as a local pee/poop tracker, yet the documented usage and implementation also support an 'attempt' event type for unsuccessful bathroom attempts. That is an intent/documentation mismatch because the code's supported domain is broader than the headline description suggests.

Static analysis

No suspicious patterns detected.