Back to skill

Security audit

Gousto Meal Picker

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent for automating Gousto meal choices, but it can modify real orders using saved OAuth session tokens without strong confirmation or credential-safety controls.

Install only if you are comfortable granting the skill access to your Gousto session and allowing it to alter pending meal-kit orders. Run with --dry-run first, keep gousto-auth.json private with restrictive permissions, avoid shared machines or command-line telemetry, and review selected meals/order IDs before enabling unattended cron runs.

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

Warning
Location
scripts/gousto-pick.mjs:29
Finding

OAuth Bearer Token Exposed Through Process Arguments

Content
View full analysis
`'${a.replace(/'/g, "'\\''")}'`).join(' '), { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024, shell: '/bin/zsh' }); ``` ### Technical Analysis The OAuth bearer token is interpolated directly into a `curl` command and passed to a shell. Shell quoting reduces command-injection exposure from individual arguments, but it does not protect the confidentiality of the resulting process arguments. While `curl` is running, the complete `Authorization: Bearer ...` header may be visible through local process inspection, privileged system monitoring, endpoint telemetry, audit facilities, or diagnostic tools that record command lines. The exposure is unnecessary because Node.js can submit HTTPS requests directly without placing credentials in a child process argument list. The recipient is the legitimate Gousto API, and no transmission to an unrelated domain was identified. The vulnerability concerns local credential disclosure rather than unauthorized network exfiltration. ### Attack Path 1. The user runs the meal picker with a valid saved Gousto session. 2. The script extracts the OAut ...[truncated 1060 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/gousto-pick.mjs:101
Finding

Sensitive Browser Authentication State Saved Without Enforced File Permissions

Content
View full analysis
/dev/null`, { encoding: 'utf8' }); const tokenData = JSON.parse(decodeURIComponent(newTokenCookie.value)); return tokenData.access_token; } ``` The same file is later read as a credential source: ```js const statePath = path.join(CONFIG_DIR, 'gousto-auth.json'); if (!fs.existsSync(statePath)) { throw new Error('No auth state found. Run agent-browser to log in first.'); } // Extract token from browser state cookies const state = JSON.parse(fs.readFileSync(statePath, 'utf8')); ``` ### Technical Analysis `gousto-auth.json` contains browser cookies holding OAuth access and refresh credentials. The documentation correctly identifies the file as sensitive and recommends `chmod 600`, but the executable refresh path does not enforce that permission after saving the state. The resulting security posture depends on the user’s umask and the behavior of `agent-browser`. If the file is created or replaced with group-readable or world-readable permissions, another local user may be able to retrieve reusable session credentials. The script also does not validate that the destination is a regular file owned by the current user. In an attacker-writable installation directory, a pre-positioned symbolic link could affect where state is saved. Exploitation of that condition requires local filesystem access and suitable directory permissions. ### Attack Path 1. The user runs the script with an expired access token. 2. The refresh flow opens Gousto through `agent-browser` and obtains fresh cookies. 3. `agent-browser state save` writes th ...[truncated 1006 chars]
Remediation
View remediation
/dev/null`, { encoding: 'utf8', }); fs.chmodSync(statePath, 0o600); ``` 2. Before reading or overwriting the file, use `fs.lstatSync()` to reject symbolic links and non-regular files. 3. Verify that the file and containing directory are owned by the expected user. 4. Store authentication state in a dedicated private directory with mode `0700`, separate from executable Skill files. 5. Update the initial setup instructions so permission hardening is performed as part of the command sequence rather than presented only as advisory guidance: ```bash agent-browser state save /gousto/gousto-auth.json chmod 600 /gousto/gousto-auth.json ``` 6. Consider using an operating-system credential store instead of a plaintext JSON browser-state file where supported. 7. Avoid suppressing all `agent-browser` errors during sensitive state writes; verify that the save succeeded before using the resulting credentials. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares shell-capable runtime requirements and provides executable shell commands, but it does not define any explicit tool scope such as allowed-tools or permissions. That leaves the agent with broader-than-necessary execution latitude, increasing the chance that a compromised or malformed workflow could invoke unintended commands or misuse available tools.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
## Security notes

- **No passwords stored** — auth uses browser cookies only (saved in `gousto-auth.json`)
- **Treat `gousto-auth.json` as sensitive** — it contains OAuth tokens. Restrict file permissions (`chmod 600`)
- **Single API endpoint** — the script only communicates with `production-api.gousto.co.uk`
- **Use `--dry-run` first** — verify selections before enabling automated ordering
- **Required runtime** — Node.js, curl, zsh shell, and agent-browser (for login/token refresh only)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation explicitly instructs access to browser-stored OAuth access and refresh tokens and explains how to use them for authenticated API calls, but provides no warning about the sensitivity of those credentials or limits on collection, storage, and reuse. In a skill that automates account actions via browser automation, this materially increases the chance of insecure token handling, credential leakage, or overbroad account access if logs, prompts, or downstream tooling capture the tokens.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The PUT /order/v2/orders/{orderId} section presents live order modification as the key endpoint and gives a complete payload template for changing recipe selections, yet it omits any warning that this performs real customer account changes. In the context of an automation skill for weekly meal selection, missing guardrails around a state-changing endpoint makes unintended or unauthorized order edits significantly more likely, with direct impact on purchases, deliveries, and account integrity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

This code refreshes authentication and saves updated browser state to gousto-auth.json, which is a file write involving sensitive session material. While the file header describes the overall flow, there is no user-facing disclosure at the point of action such as a prompt or log message indicating that auth state on disk will be updated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code performs a live PUT request that changes the user’s Gousto order contents without an interactive confirmation immediately before the write. In a skill that automates purchasing decisions tied to a real account, unintended execution, bad configuration, or misuse of a valid token can alter paid orders and delivery selections, causing integrity and financial-impact issues.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The script writes meal selection history to selections.json, which is a local file write affecting user data. There is no explicit log or prior warning that this persistence occurs, aside from the code itself.

Content

No source excerpt is available for this finding.