Back to skill

Security audit

tklr-reminders

Security checks for vulnerabilities and agentic risk

Overview

This reminder skill is coherent, but it installs a persistent alert dispatcher and has a real email-alert command-injection risk that should be reviewed before use.

Install only if you are comfortable with a local scheduled dispatcher that runs stored alert commands and modifies your reminder database. Avoid or disable email alerts until the sh -c email template is replaced with structured subprocess execution, and prefer a pinned tklr-dgraham version before setup.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/tklr_agent_wrapper.py:1899
Finding

Delayed Shell Command Injection Through Email Alert Content

Content
View full analysis
str: """Build the email delivery command — the one shape that is easy to get wrong. It nests a printf inside `sh -c` inside a TOML literal string, and each layer eats one level of escaping: the `\\\\n` written here survives TOML verbatim, becomes `\\n` after the dispatcher's shlex.split, and is finally interpreted by printf. Hand-written versions of this have shipped without a `From:` header (himalaya then exits 1 on every alert, forever) and with the newlines collapsed. Generating it removes the whole class of mistake. """ lines = [ f"From: {from_addr}", f"To: {to_addr}", "Subject: Reminder: {name} - starts {when} ({start})", "", "{name}", "When: {start} ({when})", "{description}", "", ] body = "\\\\n".join(lines) return f'sh -c "printf \\"{body}\\" | himalaya message send"' ``` The address validator excludes whitespace, commas, and extra `@` characters, but does not exclude sh ...[truncated 5942 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install.sh:150
Finding

Unpinned Third-Party Package Installation During Setup

Content
View full analysis
=3.12}" echo " installing tklr-dgraham (python $PYSPEC) ..." # --quiet: uv otherwise lists all 28 resolved packages. That output is # noise to a human and actively harmful to an agent, which has to read it # before deciding what to do next -- see run_installer() in the wrapper. if ! "$UV" tool install --quiet --python "$PYSPEC" tklr-dgraham; then warn "uv could not install tklr." warn "If pip reported 'Could not find a version that satisfies the" warn "requirement tklr-dgraham', that is a Python version mismatch, NOT a" warn "missing package — every release requires >= 3.12." exit 1 fi hash -r 2>/dev/null || true if ! command -v tklr >/dev/null 2>&1; then # uv puts shims in ~/.local/bin; if that is not on PATH it is invisible. warn "installed, but 'tklr' is not on PATH — run: $UV tool update-shell" exit 1 fi ok "installed — $(tklr --version 2>&1 | head -1) at $(command -v tklr)" ``` ### Technical Analysis The installation command names `tklr-dgraham` without an exact version, lockfile, artifact hash, or immutable package reference. Consequently, setup resolves whichever compatible release and transitive dependency graph the package index serves at installation time. The subsequent version check establishes compatibility constraints but does not establish artifact identity or integrity. A minimum-version check cannot ensure that the downloaded release is the same release that was reviewed during this audit. This creates a supply-chain trust gap between the audited repository and the code executed on the user’s system. The installed package is central to workspace initialization, parsing, database operat ...[truncated 1501 chars]
Remediation
View remediation
" ``` 2. Use a committed lockfile that fixes the complete transitive dependency graph. 3. Require cryptographic hashes for downloaded distributions where the package workflow supports them. 4. Prefer immutable, signed release artifacts and verify signatures before installation. 5. Record the approved version and integrity metadata in the repository. 6. Fail closed if the installed version or artifact digest differs from the approved value. 7. Review release changes and rerun security and compatibility tests before updating the pin. 8. Avoid silently upgrading an existing installation as part of ordinary setup. 9. Preserve visible dependency-resolution logs or an installation manifest so users can determine exactly what was installed. 10. Consider distributing a reproducibly built, integrity-verified environment instead of resolving the dependency graph dynamically on each machine. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (65)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill appears to support execution of configured delivery commands, direct database mutation, and cron-driven infrastructure, all of which are substantially more privileged than a normal reminder interface. The 'Requires Hermes Agent' framing can further obscure that some behaviors may still run locally and modify system state independently.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill appears to support execution of configured delivery commands, direct database mutation, and cron-driven infrastructure, all of which are substantially more privileged than a normal reminder interface. The 'Requires Hermes Agent' framing can further obscure that some behaviors may still run locally and modify system state independently.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The skill appears to support execution of configured delivery commands, direct database mutation, and cron-driven infrastructure, all of which are substantially more privileged than a normal reminder interface. The 'Requires Hermes Agent' framing can further obscure that some behaviors may still run locally and modify system state independently.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 154)May include surrounding context.

md
4. **Load `references/using-the-wrapper.md` before composing any command.**

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 192)May include surrounding context.

md
4. **Load `references/using-the-wrapper.md` before composing any command.**

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 363)May include surrounding context.

md
4. **Load `references/using-the-wrapper.md` before composing any command.**

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 185)May include surrounding context.

md
| `scripts/tklr_agent_wrapper.py` | `$R` — the one interface for every operation |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 214)May include surrounding context.

md
| `scripts/tklr_agent_wrapper.py` | `$R` — the one interface for every operation |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 291)May include surrounding context.

md
| `scripts/tklr_agent_wrapper.py` | `$R` — the one interface for every operation |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 186)May include surrounding context.

md
| `scripts/install.sh` | installs tklr; `setup` runs it for you — never call it yourself |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 305)May include surrounding context.

md
| `scripts/install.sh` | installs tklr; `setup` runs it for you — never call it yourself |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 190)May include surrounding context.

md
| `scripts/tklr_mutate.py` | low-level record edits |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 193)May include surrounding context.

md
| `references/setup.md` | the whole setup procedure — load when setup is incomplete |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 261)May include surrounding context.

md
| `references/setup.md` | the whole setup procedure — load when setup is incomplete |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 195)May include surrounding context.

md
| `references/tklr-syntax.md` | underlying tklr grammar; only needed for `--raw` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 245)May include surrounding context.

md
| `references/tklr-syntax.md` | underlying tklr grammar; only needed for `--raw` |

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

chat_send_command returns a raw shell command by interpolating target and message directly into a command string that is later executed by the dispatcher. Because message contents include reminder text and placeholders, and target may come from host-discovered identifiers or user selection, shell metacharacters could alter command structure at execution time, enabling command injection and scheduled arbitrary code execution.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/install.sh (reported line 230)May include surrounding context.

sh
fi

# The wrapper stays in the skill directory, but a scheduled run has no way to
# learn where that is: the blueprint prompt is copied verbatim, so the
# ${HERMES_SKILL_DIR} token SKILL.md relies on is never substituted there. The
# skill directory has already moved once (a symlink under the host's skills dir
# to a git checkout named by skills.external_dirs) and every hardcoded path

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/reset.sh (reported line 248)May include surrounding context.

sh
step "installed dispatcher"
if [[ -f "$DISPATCHER" ]]; then
    act "rm $DISPATCHER"
    [[ $DRY_RUN -eq 0 ]] && rm -f "$DISPATCHER"
else
    skip "$DISPATCHER"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/reset.sh (reported line 266)May include surrounding context.

sh
step "installed dispatcher"
if [[ -f "$DISPATCHER" ]]; then
    act "rm $DISPATCHER"
    [[ $DRY_RUN -eq 0 ]] && rm -f "$DISPATCHER"
else
    skip "$DISPATCHER"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/reset.sh (reported line 276)May include surrounding context.

sh
step "installed dispatcher"
if [[ -f "$DISPATCHER" ]]; then
    act "rm $DISPATCHER"
    [[ $DRY_RUN -eq 0 ]] && rm -f "$DISPATCHER"
else
    skip "$DISPATCHER"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/reset.sh (reported line 278)May include surrounding context.

sh
step "installed dispatcher"
if [[ -f "$DISPATCHER" ]]; then
    act "rm $DISPATCHER"
    [[ $DRY_RUN -eq 0 ]] && rm -f "$DISPATCHER"
else
    skip "$DISPATCHER"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/reset.sh (reported line 316)May include surrounding context.

sh
step "installed dispatcher"
if [[ -f "$DISPATCHER" ]]; then
    act "rm $DISPATCHER"
    [[ $DRY_RUN -eq 0 ]] && rm -f "$DISPATCHER"
else
    skip "$DISPATCHER"
fi

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/reset.sh (reported line 278)May include surrounding context.

sh
act "rm ${LOG_GLOB}*"
    [[ $DRY_RUN -eq 0 ]] && rm -f "${LOG_GLOB}"*
    # the lock file lives beside the log
    [[ $DRY_RUN -eq 0 ]] && rm -f "$HERMES_HOME/logs/.tklr-alerts.lock"
else
    skip "${LOG_GLOB}*"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
78% confidence
Finding

This line performs 'rm -rf' on TKLR_HOME, which can be redirected by the environment. Although the script includes guard_tklr_home and several sensible checks, the protection is heuristic and not strict path allowlisting; an attacker or test environment could point TKLR_HOME at an arbitrary non-root directory that merely contains a 'tklr.db' or 'config.toml' file, causing recursive deletion of unintended data. In a reset script, destructive behavior is expected, but environment-controlled recursive deletion still materially raises risk.

Content

Scanner excerpt · scripts/reset.sh (reported line 325)May include surrounding context.

sh
step "tklr workspace (YOUR REMINDERS)"
if [[ -d "$TKLR_HOME" ]]; then
    act "rm -rf $TKLR_HOME"
    [[ $DRY_RUN -eq 0 ]] && rm -rf "$TKLR_HOME"
else
    skip "$TKLR_HOME"
fi

Static analysis

No suspicious patterns detected.