Back to skill

Security audit

Cookidoo

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its Cookidoo meal-planning purpose, but it stores and handles account session data in ways users should review carefully.

Install only if you are comfortable giving this CLI access to your Cookidoo account. Prefer the bundled reviewed file or a pinned release instead of unpinned git install commands, avoid passing passwords as command-line flags, and protect or delete the local cookie/token files when done.

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

Warning
Location
tmx_cli.py:291
Finding
Authentication Cookies and Search Tokens Are Stored Without Restrictive File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `tmx_cli.py:291-307` and `tmx_cli.py:654-678` **Vulnerability Type**: Insecure local storage of authentication material **Risk Level**: Medium ### Vulnerable Code ```python def save_cookies_from_jar(jar: CookieJar): """Save cookies from CookieJar to JSON file (Puppeteer-compatible format).""" cookies_list = [] for cookie in jar: cookies_list.append({ "name": cookie.name, "value": cookie.value, "domain": cookie.domain, "path": cookie.path, "expires": cookie.expires or -1, "httpOnly": cookie.has_nonstandard_attr("HttpOnly"), "secure": cookie.secure, "session": cookie.expires is None, }) with open(COOKIES_FILE, "w", encoding="utf-8") as f: json.dump(cookies_list, f, ensure_ascii=False, indent=2) return cookies_list ``` ```python def get_search_token(cookies: dict[str, str]) -> Optional[str]: """Get Algolia search token from Cookidoo API.""" # Check cached token if SEARCH_TOKEN_FILE.exists(): try: with open(SEARCH_TOKEN_FILE, "r") as f: cached = json.load(f) # Check if still valid (with 5 min buffer) if cached.get("validUntil", 0) > dt.datetime.now().timestamp() + 300: return cached.get("apiKey") except: pass # Fetch new token url = f"{COOKIDOO_BASE}/search/api/subscription/token" status, body = fetch(url, cookies) if status != 200: return None try: data = json.loads(body) # Cache token with open(SEARCH_TOKEN_FILE, "w") as f: json.dump(data, f) return data.get("apiKey") ``` ### Technical Analysis The CLI writes reusable Cookidoo session cookies and an Algolia search API token using ordinary `open(..., "w")` operations. It does not explicitly create these files with owne ...[truncated 2474 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store credentials in a dedicated per-user data directory rather than beside the executable, such as an appropriate platform-specific application data directory. 2. Create credential files with owner-only permissions from the outset. On POSIX systems, use `os.open()` with mode `0o600`, then write through the resulting file descriptor. 3. Explicitly set existing credential files to mode `0600` and reject files owned by another user or having unsafe permissions. 4. Use atomic writes through a temporary owner-only file followed by `os.replace()` to prevent partial files and reduce race conditions. 5. Store only cookies required for Cookidoo authentication instead of serializing the entire OAuth cookie jar. 6. Prefer an operating-system credential manager or keyring for reusable session material. 7. Provide a logout or session-revocation operation that securely removes cached cookies and tokens. 8. Document the actual storage location and security sensitivity of each file. 9. Avoid broad exception handlers around secret loading because they can conceal permission and integrity problems that should be reported to the user. A POSIX-oriented implementation can follow this pattern: ```python import os def secure_json_write(path: Path, data: object) -> None: flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC fd = os.open(path, flags, 0o600) try: with os.fdopen(fd, "w", encoding="utf-8") as stream: json.dump(data, stream, ensure_ascii=False, indent=2) except Exception: try: os.close(fd) except OSError: pass raise ``` ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:42
Finding
Documentation Recommends Executing Mutable, Unpinned Remote Source<![CDATA[ ## Vulnerability Details **File Location**: `README.md:42-45` and `README.md:188-205` **Vulnerability Type**: Unpinned remote-source installation and execution **Risk Level**: Medium ### Vulnerable Instructions ```bash # With uvx (recommended) — runs instantly without installation uvx --from git+https://github.com/Lars147/tmx-cli tmx login # Log in, then get started! uvx --from git+https://github.com/Lars147/tmx-cli tmx search "Pasta" ``` ```bash # Run directly — no installation needed uvx --from git+https://github.com/Lars147/tmx-cli tmx --help # Or install globally uv tool install git+https://github.com/Lars147/tmx-cli tmx --help # Update to latest version uv tool install --upgrade git+https://github.com/Lars147/tmx-cli ``` ```bash pipx install git+https://github.com/Lars147/tmx-cli tmx --help # Update pipx install --force git+https://github.com/Lars147/tmx-cli ``` ### Technical Analysis The recommended installation commands reference a Git repository without specifying an immutable release tag or commit hash. Consequently, the effective code installed or executed can change after this Skill version has been audited. This is especially sensitive because the first recommended command invokes the login workflow. A malicious or compromised future revision could execute under the user's account and capture Cookidoo credentials, authentication cookies, local files, or other process-accessible data. No malicious remote payload retrieval exists in the audited `tmx_cli.py` itself. The risk arises from the installation instructions directing users to trust and execute mutable upstream source rather than the reviewed artifact. ### Attack Path 1. The upstream GitHub repository, maintainer account, default branch, or release workflow is compromised or receives a malicious change. 2. A user follows the documented `uvx`, `uv tool install`, or `pipx` command without pinning a version or commit. 3. The package manager downloads and builds the current u ...[truncated 1040 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Publish versioned package releases and recommend installation from a trusted package registry using an exact version. 2. If Git installation is necessary, pin examples to an immutable, reviewed commit: ```bash uvx --from "git+https://github.com/Lars147/tmx-cli@<audited-commit-sha>" tmx --help ``` 3. Do not use an unpinned default branch in the recommended login command. 4. Provide release checksums, signed tags, or verifiable build provenance. 5. Separate installation verification from authentication. Users should verify the package version and source before entering credentials. 6. Document an upgrade process that identifies the target version and allows users to review release notes before execution. 7. Remove the example that supplies a password directly on the command line: ```bash tmx login --email user@example.com --password secret ``` Command-line passwords may be retained in shell history or exposed through process inspection. The existing hidden `getpass` prompt should be the documented and preferred authentication method. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The README instructs users to execute code directly from a GitHub repository via `uvx --from git+...` without pinning to a specific commit, tag, or release. That means future repository changes—or a compromised upstream account/repo—could cause users to run unexpected code, which is particularly relevant because this tool is explicitly positioned for AI-agent usage and easy execution.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
This example again encourages running the latest code directly from a Git repository with no version pinning. Users and agents following the README may unknowingly execute altered code later, turning documentation into a supply-chain execution path.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The installation section repeats unpinned `uvx --from git` usage, creating an implicit trust-on-latest pattern. In an agent-integrated CLI, this increases risk because automation may execute the command non-interactively and at scale.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The README shows `tmx login --email user@example.com --password secret`, which exposes credentials in shell history, terminal logs, process listings, and possibly agent telemetry. Because this skill is designed for terminal and AI-assistant workflows, the chance of accidental secret leakage is higher than in ordinary interactive usage.

Session Persistence

Medium
Category
Rogue Agent
Content
### ⚡ Shell Completion

```bash
# Bash (add to ~/.bashrc)
eval "$(tmx completion bash)"

# Zsh (add to ~/.zshrc)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
# Bash (add to ~/.bashrc)
eval "$(tmx completion bash)"

# Zsh (add to ~/.zshrc)
eval "$(tmx completion zsh)"

# Fish (run once)
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill exposes operational capabilities that imply file access, file modification, and network use, but it does not declare any tool scope or permissions boundaries in the manifest. In an agent environment, that makes it harder to enforce least privilege and increases the risk that the skill can be invoked with broader access than users or reviewers expect, especially because it performs OAuth login and manages local/exported data.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The manifest uses broad trigger terms such as 'recipe', 'meal plan', and cooking-related German keywords that can match ordinary conversation and cause the skill to activate unexpectedly. Over-broad activation is risky here because the skill can perform networked account actions and local write/destructive operations, so accidental invocation could lead to unintended data changes or unnecessary account interaction.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation explicitly states that Cookidoo credentials are stored locally in `secrets/cookidoo.env`, but provides no warning about secure handling, file permissions, encryption, or alternatives to storing raw credentials. In a skill that interfaces with a real user account and shopping/meal-planning data, this increases the risk of credential disclosure through source control, local compromise, backups, or accidental sharing.

Session Persistence

Medium
Category
Rogue Agent
Content
errors.append(f"{cat_id}: Kategorie-Name nicht gefunden")
            continue
        
        # Create URL-friendly key
        cat_key = cat_name.lower().replace(" ", "-").replace("ä", "ae").replace("ö", "oe").replace("ü", "ue").replace("ß", "ss")
        cat_key = re.sub(r'[^a-z0-9-]', '', cat_key)
Confidence
78% confidence
Finding
This finding appears mislabeled in the snippet, but the file does implement persistent session handling by saving authentication cookies to disk for reuse across runs. In a CLI skill that can mutate meal plans, favorites, and shopping lists, stolen session cookies enable unauthorized account actions without needing the user's password.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code persists session cookies and the search token to local JSON files without setting restrictive permissions or clearly informing the user that authentication material is being stored on disk. On multi-user systems or in shared agent environments, these files may be read by other local principals and reused to impersonate the user.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Allowing a password to be passed via a CLI flag can expose credentials through shell history, process listings, audit logs, and agent telemetry. In an agent skill context this is more dangerous because orchestration layers often log command arguments, making accidental credential disclosure likely.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
Multiple demo and usage examples show the tool outputting German interface text such as `WOCHENPLAN`, `Suche in Cookidoo`, and `Einkaufsliste`, but the README does not explain that the tool is German-only or offer any language/locale option. This can violate language policy expectations when a skill effectively forces a specific locale without user opt-in.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The code fixes the service base and locale to German (`cookidoo.de`, `de-DE`) and also sends German-biased `Accept-Language` headers throughout the login and fetch flows. This enforces a specific language/locale behavior without presenting any user option or documenting it as a justified region-specific constraint.

Description-Behavior Mismatch

Low
Confidence
90% confidence
Finding
The manifest describes recipe search, week plan management, shopping list generation, favorites, and recipe details via tmx-cli. This file additionally implements exporting shopping list contents to a user-specified local path, which is a broader local file-write capability not mentioned in the skill description.

Static analysis

No suspicious patterns detected.