Back to skill

Security audit

Knuspr

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for Knuspr grocery automation, but it stores/uses sensitive login material in risky ways and can change a live shopping account.

Install only if you are comfortable giving an agent-assisted CLI access to your Knuspr account. Prefer interactive login over command-line passwords, environment variables, or ~/.knuspr_credentials.json; protect or remove any saved session/credential files; and require explicit confirmation before adding many items, repeating orders, reserving slots, clearing carts, or changing lists/favorites.

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
knuspr_cli.py:160
Finding
Session Cookies Are Persisted Without Enforced Restrictive Permissions## Vulnerability Details **File Location**: `knuspr_cli.py`, lines 160–167 **Vulnerability Type**: Insecure storage of reusable authentication tokens **Risk Level**: High ```python def _save_session(self) -> None: """Save session cookies to file.""" session_data = { "cookies": self.cookies, "user_id": self.user_id, "address_id": self.address_id, } with open(SESSION_FILE, "w") as f: json.dump(session_data, f) ``` ### Technical Analysis The application serializes reusable authentication cookies, the user identifier, and the address identifier into `~/.knuspr_session.json`. The file is opened using the default process permissions, without securely creating it with mode `0600` or verifying its ownership and permissions. Consequently, the file's effective permissions depend on the user's current `umask` and any pre-existing file metadata. In an environment with a permissive `umask`, or where the destination file was created previously with weak permissions, another local user or process may be able to read the session cookies. The cookies are automatically attached to subsequent requests through the `Cookie` header. They therefore constitute reusable authentication material rather than harmless application configuration. ### Attack Path 1. A user authenticates to Knuspr through the CLI. 2. `_save_session()` writes the returned cookies to `~/.knuspr_session.json`. 3. The file receives permissions derived from the process `umask`, or retains insecure permissions from an existing file. 4. Another local user, compromised process, or application running under an account with read access obtains the cookie values. 5. The attacker replays the cookies in requests to Knuspr. 6. If the server-side session remains valid, the attacker operates within the victim's authenticated Knuspr session. Exploitation requires local read access to the session file or its contents; the ...[truncated 675 chars]
Remediation
## Remediation Suggestions 1. Create the session file atomically with owner-only permissions: - Use `os.open()` with flags such as `O_WRONLY | O_CREAT | O_TRUNC` and mode `0o600`. - Wrap the resulting descriptor with `os.fdopen()`. 2. Write to a securely created temporary file in the same directory, flush and synchronize it, set mode `0600`, and atomically replace the destination. 3. Before reading an existing session file: - Verify that it is a regular file. - Verify that it is owned by the current user. - Reject symlinks where the platform supports safe no-follow behavior. - Reject or repair group-readable and world-readable permissions. 4. Store reusable session secrets in the operating system's credential manager or keyring where feasible. 5. Apply equivalent protections to any other file that may contain credentials or tokens. 6. Update the documentation so that “secure session storage” is claimed only after these controls are enforced. 7. On logout, continue deleting the local session file and invalidate the session server-side whenever possible.

T09 · Insecure Skill Coding Practices

Warning
Location
knuspr_cli.py:1321
Finding
Password Can Be Supplied Through Process-Visible Command-Line Arguments## Vulnerability Details **File Location**: `knuspr_cli.py`, lines 1321–1322 and line 4274; `README.md`, line 136; `references/commands.md`, line 149 **Vulnerability Type**: Exposure of credentials through command-line arguments and shell history **Risk Level**: Medium ```python if getattr(args, 'password', None): password = args.password ``` ```python auth_login.add_argument("--password", "-p", help="Passwort") ``` The insecure invocation is also explicitly documented: ```bash knuspr auth login -e user@mail.de -p geheim ``` The command reference similarly advertises the option: ```text auth login [-e email -p pass] ``` ### Technical Analysis Command-line arguments are not an appropriate transport for passwords. Depending on the operating system and execution environment, arguments may be exposed through process inspection interfaces, monitoring or endpoint-management products, audit logs, diagnostic reports, terminal-session recording, automation logs, and shell history. Although the implementation masks the password when printing login status, that masking does not remove the secret from the original process argument vector or the user's shell history. The documentation increases the likelihood of exposure by presenting the password argument as a supported login method. Interactive collection through `getpass.getpass()` is already implemented and is safer because it avoids terminal echo and does not place the password in the command line. ### Attack Path 1. A user follows the documented example and executes `knuspr auth login -e user@mail.de -p geheim`. 2. The shell may persist the entire command in its history file. 3. While the command is running, the password may also be visible through process-inspection facilities, subject to platform access controls. 4. Local monitoring software, logs, another authorized local user, or an attacker who later obtains access to shell history retrieves the ...[truncated 959 chars]
Remediation
## Remediation Suggestions 1. Remove or deprecate the `--password` and `-p` arguments. 2. Continue using `getpass.getpass()` for interactive authentication. 3. For automation, accept credentials through a protected standard-input channel or an operating-system credential manager rather than command-line arguments. 4. If environment-variable support remains available, document that environment variables may also be observable in some execution and diagnostic environments. 5. Remove all password-bearing command examples from `README.md` and `references/commands.md`. 6. Emit a security warning if the legacy password option is temporarily retained for compatibility. 7. Avoid logging the parsed argument namespace, login payload, environment, or exceptions that could contain credentials. 8. Recommend credential rotation to users who previously supplied passwords through command-line arguments on shared or monitored systems.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (17)

Credential Access

High
Category
Privilege Escalation
Content
### Option 3: Credentials-Datei

```bash
cat > ~/.knuspr_credentials.json << 'EOF'
{
  "email": "user@example.com",
  "password": "geheim"
Confidence
96% confidence
Finding
The README explicitly instructs users to store plaintext email and password values in ~/.knuspr_credentials.json. Storing reusable login credentials in a plaintext file creates a high-value target for local compromise, malware, backups, or accidental disclosure.

Credential Access

High
Category
Privilege Escalation
Content
"password": "geheim"
}
EOF
chmod 600 ~/.knuspr_credentials.json
knuspr auth login
```
Confidence
93% confidence
Finding
This section reinforces the use of a plaintext credentials file as part of the normal login flow. Even with chmod 600, secrets remain accessible to the local user account, malware running as that user, and potentially through backups or developer tooling.

Credential Access

High
Category
Privilege Escalation
Content
| Datei | Beschreibung |
|-------|--------------|
| `~/.knuspr_session.json` | Session-Cookies (automatisch verwaltet) |
| `~/.knuspr_credentials.json` | Gespeicherte Login-Daten (optional) |
| `~/.knuspr_config.json` | Benutzer-Präferenzen |

## 🛠️ Abhängigkeiten
Confidence
90% confidence
Finding
Documenting the exact locations of session cookies and stored credentials makes it easier for operators and agents to access them, but also lowers the barrier for misuse or exfiltration if an integration overreaches. In a skill intended for automation, exposing these paths is more sensitive because agents may be tempted to read or manipulate them directly.

Credential Access

High
Category
Privilege Escalation
Content
# Configuration
BASE_URL = "https://www.knuspr.de"
SESSION_FILE = Path.home() / ".knuspr_session.json"
CREDENTIALS_FILE = Path.home() / ".knuspr_credentials.json"
CONFIG_FILE = Path.home() / ".knuspr_config.json"

# Exit codes
Confidence
95% confidence
Finding
The presence of a dedicated plaintext credentials file path in the user's home directory indicates the skill is designed to access stored account secrets directly. In this skill context, that is especially sensitive because the same code can then modify carts, reserve slots, inspect order history, and perform other authenticated account actions without explicit per-session credential entry.

Credential Access

High
Category
Privilege Escalation
Content
| `auth status` | Check login status |

Env vars: `KNUSPR_EMAIL`, `KNUSPR_PASSWORD`
Credential file: `~/.knuspr_credentials.json`
Confidence
81% confidence
Finding
Referencing environment variables and a credential file is not inherently malicious, but it normalizes secret locations that an agent or downstream tooling could read, surface, or mishandle. In a skill context that manages purchases and account actions, exposed credentials could enable unauthorized account access, shopping actions, and leakage of account or order data.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
alias knuspr="python3 /pfad/zu/knuspr_cli.py"

# Option B: Ins PATH kopieren
sudo cp knuspr_cli.py /usr/local/bin/knuspr
```

**Voraussetzungen:** Python 3.8+ (keine externen Dependencies!)
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README documents state-changing operations like adding items to a cart, clearing a cart, reserving slots, and repeating orders without prominently warning that these actions modify a real user account and may create financial or delivery consequences. In an AI-agent context, this increases the chance of unintended purchases or account changes if an agent follows examples blindly.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The credential-handling section shows passing passwords via command line, environment variables, and a local credentials file without strong privacy caveats about shell history, process listings, log capture, and local secret exposure. In an agent setting, these examples can normalize insecure secret handling and lead to credential leakage.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"password": "geheim"
}
EOF
chmod 600 ~/.knuspr_credentials.json
knuspr auth login
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes a bundled Python CLI that can use environment variables for credentials, perform network operations against Knuspr.de, and likely modify local state, yet the manifest declares no explicit tool scope or permission boundaries. This increases the risk of over-privileged execution and makes it harder for the platform to constrain or audit sensitive capabilities such as credential access, outbound requests, and file writes.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger terms include very broad shopping-related language such as groceries, shopping list tasks, Warenkorb, and Lebensmittel, which can cause the skill to activate for general retail or household-planning requests that are not specifically about Knuspr. In this skill, unintended activation is more dangerous because the skill can access account-linked shopping functions and perform state-changing actions like adding items, clearing carts, or reserving delivery slots.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The Accept-Language header is hard-coded to prefer de-DE/de, which imposes a specific language/locale behavior on all API requests. This is a natural-language policy issue because the skill does not offer a language choice or clearly justify the locale restriction as region-specific behavior.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Session cookies and account identifiers are persisted to a JSON file in the user's home directory with no permission hardening or warning that authentication state is stored on disk. If that file is accessed by another local user, process, or backup/logging mechanism, it may enable account takeover or unauthorized shopping actions using the saved session.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The code silently sources credentials from environment variables and a local credentials file, which expands its access beyond interactive grocery management into credential harvesting from the host environment. In an agent-skill context, this is dangerous because the skill can authenticate using secrets the user never explicitly supplied in-session, violating user expectations and least-privilege boundaries.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
Credentials are read from KNUSPR_EMAIL/KNUSPR_PASSWORD and a local JSON file without any prominent warning, consent flow, or secure-storage guarantees. This creates a secrecy and transparency problem: users may not realize the skill is ingesting sensitive credentials from ambient sources, increasing the chance of accidental exposure or unsafe deployment practices.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill metadata describes grocery management features, but the code also implements purchase-history analytics and meal/recommendation functionality over prior orders. This scope mismatch matters because it enables additional collection and processing of sensitive behavioral data without clear disclosure, which can surprise users and downstream agents relying on the manifest for least-privilege decisions.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The authentication documentation explicitly encourages passing credentials on the command line and discloses storage locations for secrets without any warning about exposure risks. Command-line passwords can be visible in shell history, process listings, logs, or agent telemetry, which is especially risky in an automation skill that may compose or echo commands.

Static analysis

No suspicious patterns detected.