Back to skill

Security audit

MILKEE Swiss Accounting

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the advertised MILKEE accounting integration, but it needs review because it can change business records and its documentation includes realistic API credential examples.

Review before installing. Use only your own MILKEE token, treat it as a secret, avoid copying the realistic examples from the docs, and rotate any token if you pasted it into logs, chat, shell history, or a committed config file. Install only if you are comfortable giving this skill authority to read and modify MILKEE business records such as customers, projects, products, tasks, and time entries.

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

T09 · Insecure Skill Coding Practices

Warning
Location
INSTALLATION_GUIDE.md:20
Finding

Credential-Shaped MILKEE API Tokens and Company Identifiers Embedded in Documentation

Content
View full analysis

Vulnerability Details

File Location: INSTALLATION_GUIDE.md:20-22, INSTALLATION_GUIDE.md:79-86, references/configuration.md:18-21, references/configuration.md:57-65, and references/api-endpoints.md:13-16
Vulnerability Type: Hardcoded credential-like secrets in distributed documentation
Risk Level: Medium

Vulnerable Code Snippets

INSTALLATION_GUIDE.md:20-22

markdown
4. Combine as: `USER_ID|API_KEY`

**Example**: `28014|MqF8I04nbuFd4aT4A5Y6hBqaDDd9T2sjVT5Xu2ZAc799c9d2`

INSTALLATION_GUIDE.md:79-86

json
{
  "skills": {
    "milkee": {
      "env": {
        "MILKEE_API_TOKEN": "28014|MqF8I04nbuFd4aT4A5Y6hBqaDDd9T2sjVT5Xu2ZAc799c9d2",
        "MILKEE_COMPANY_ID": "4086"
      }

references/configuration.md:18-21

markdown
**Example**:

28014|MqF8I04nbuFd4aT5Xu2ZAc799c9d2

text

references/configuration.md:57-65

bash
Test configuration:

```bash
export MILKEE_API_TOKEN="28014|MqF8I04nbuFd4aT4A5Y6hBqaDDd9T2sjVT5Xu2ZAc799c9d2"
export MILKEE_COMPANY_ID="4186"

python3 scripts/milkee.py list_projects
text

`references/api-endpoints.md:13-16`

```markdown
Example:

Authorization: Bearer 28014|MqF8I04nb2ZAc799c9d2

text

Technical Analysis

The documentation contains several values that conform to the exact production authentication format expected by the implementation: a numeric MILKEE user identifier, a pipe separator, and an API-key-like string. These values are presented alongside realistic numeric company identifiers.

The application reads this token from MILKEE_API_TOKEN and transmits it as a bearer credential to the MILKEE API. Consequently, any valid example token would be directly usable without further transformation. Static analysis cannot establish whether these values are currently active, expired, fabricated, or restricted. Nevertheless, distributing realistic credential-shaped values creat ...[truncated 1652 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove every realistic token, user ID, and company ID from all documentation and release artifacts.
  2. Replace them with unmistakably synthetic placeholders, for example:
    text
    MILKEE_API_TOKEN="USER_ID|REDACTED_API_KEY"
    MILKEE_COMPANY_ID="YOUR_COMPANY_ID"
    
  3. If any displayed value originated from a real account, revoke or rotate the corresponding MILKEE API key immediately.
  4. Review MILKEE authentication and API access logs for use of the exposed identifiers, including access from unexpected addresses or modifications to company data.
  5. Search repository history, packaged Skill archives, release attachments, mirrors, and caches for earlier copies of the values. Removing them only from the current version does not eliminate historical exposure.
  6. Add automated secret scanning to version-control hooks and CI release checks. Configure patterns for the documented MILKEE token format as well as high-entropy strings.
  7. Use clearly invalid example identifiers and explicitly label all examples as placeholders.
  8. Apply least-privilege permissions to API identities and rotate API keys regularly to reduce the impact of future disclosure.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Tainted flow: 'req' from os.getenv (line 34, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/milkee.py (reported line 49)May include surrounding context.

python
data = {k: v for k, v in data.items() if v is not None}
            req.data = json.dumps(data).encode()
        
        with urllib.request.urlopen(req, timeout=10) as response:
            return json.loads(response.read().decode())
    
    except urllib.error.HTTPError as e:

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The authentication section exposes a bearer token example without redaction or safety guidance, which is especially risky because this skill handles business accounting data and project/customer records. Users or downstream systems may copy this value verbatim, and models may surface it in responses, turning documentation into a credential disclosure vector.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation includes a bearer token in the exact format used for authentication (USER_ID|API_KEY), and the example value looks live rather than clearly fake or redacted. Even if intended as an example, embedding credential-like material in a skill reference risks accidental reuse, leakage through model outputs, or unauthorized access if the token is valid.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide shows a live-looking API token in a realistic credential format without clearly marking it as fake, redacted, or non-reusable. Readers may mistakenly reuse it, normalize exposing secrets in documentation, or leak a real credential if the example was copied from an actual account.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions direct users to place API credentials in a local JSON config file in plaintext, but do not warn about risks such as local disclosure, backups, accidental commits, or overly broad file permissions. For an accounting integration, exposed tokens could grant access to business time tracking, customer, and project data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The test instructions tell users to export credentials directly in the shell without warning that commands may be exposed through shell history, terminal logging, shared sessions, or process inspection in some environments. This increases the chance of credential disclosure during setup and testing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to place a long-lived API token directly into a local JSON configuration file in plaintext, but provides no warning about secret handling, file permissions, rotation, or safer alternatives. This increases the chance of accidental credential exposure through backups, dotfile syncing, screenshots, shell support requests, or compromise of the local workstation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documentation declares required environment variables and describes behavior that reads environment secrets, writes a persistent timer file, and calls a remote API, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates an authorization gap: an agent or platform may permit broader file/network access than users expect, increasing the risk of unintended secret access, local file writes, or outbound data transmission.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

A live-looking bearer token in reference documentation can be propagated into prompts, outputs, logs, and code samples, causing secondary credential exposure even if not actively exploited. In the context of an integration skill, this is more dangerous because the content is likely to be consulted operationally and reused during real API interactions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The configuration guide includes realistic-looking example credentials in the exact format required by the service, including a concrete user ID, API-key-like secret, and company identifier. Even if intended as sample data, publishing live-looking secrets in documentation can expose real accounts if they were copied from an actual environment, and it normalizes unsafe secret handling for users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation presents live-looking API token examples without prominently stating that they must be replaced and treated as sensitive secrets. In a skill whose primary function is integrating with an accounting platform, this is especially risky because users are likely to copy the examples verbatim and because compromised credentials could expose business financial and project data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The verification section instructs users to export a full API token directly in the shell using a live-looking example secret. This creates risk of credential disclosure through shell history, process inspection, terminal logs, screenshots, and copy/paste reuse, especially because the token appears ready to use rather than obviously fictitious.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The verification instructions tell users to export credentials directly in the shell without warning about shell history, audit logs, shared terminals, or other local exposure channels. Because this skill interfaces with MILKEE accounting data, leaked credentials could permit unauthorized access to customer, project, time-tracking, and potentially billing-related records.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The credential setup section instructs users to place an API token in an environment variable and shows its format, but it does not warn that the token is sensitive and must not be pasted into chats, logs, screenshots, shell history, or committed config files. In an agent context, this omission can lead to accidental credential disclosure and unauthorized access to accounting data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill states that timer state is saved persistently to ~/.milkee_timer and that work descriptions and project context are used for timing, but it does not warn users that potentially sensitive client names, project names, or work notes may be written to local disk. On shared or insufficiently secured systems, this can expose business activity metadata and descriptions to other local users or backup/sync systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The timer state is persisted to a predictable file in the user's home directory without setting restrictive permissions or warning the user that work descriptions and project metadata are stored locally. On multi-user systems or misconfigured environments, this can expose potentially sensitive business activity details or allow local tampering with the stored timer data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The CLI sets the default customer country code to CH, which imposes a locale-specific default in natural-language-facing behavior. There is no explicit opt-in or justification in the file indicating that this skill is intended only for Swiss users or Swiss accounting workflows.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.