Back to skill

Security audit

boka-tvattid

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the advertised laundry booking tasks, but its debug mode can expose login/session details in logs.

Review before installing. Use only if you are comfortable giving the skill your Boka tvättid building, apartment number, and PIN, and avoid running it with BOKA_DEBUG set until debug output is redacted. Confirm each booking or cancellation yourself and do not pass PINs in chat or shell history.

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
scripts/bokatvattid.py:34
Finding
Authentication Token Disclosure Through Debug Logging<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bokatvattid.py`, lines 34–45 **Vulnerability Type**: Sensitive session token exposure through debug output **Risk Level**: Medium ### Vulnerable Code ```python def _post(url, params): # Form-encoded POST: credentials stay in the request body, never in a URL # (query strings end up in server/proxy access logs; bodies normally do not). body = urllib.parse.urlencode(params).encode("utf-8") req = urllib.request.Request(url, data=body, method="POST", headers={"Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded"}) with urllib.request.urlopen(req, timeout=20) as r: d = json.loads(r.read().decode("utf-8")) if os.environ.get("BOKA_DEBUG"): print(json.dumps(d, ensure_ascii=False)[:2000], file=sys.stderr) return d ``` The affected function is used by the authentication flow at lines 137–143: ```python def login(pin, building, apartment): d = _post(LEGACY, {"method": "checkLogin2", "buildingid": building, "pincode": pin, "apartmentnumber": apartment, "lang": "1"}) if d.get("error") not in (0, "0"): raise BokaError("Inloggning misslyckades: %s (fel PIN/lägenhet?)" % d.get("message", "")) b = d["body"] return b["Token"], str(b["ApartmentID"]) ``` ### Technical Analysis The generic `_post()` function serializes and prints the raw decoded server response whenever the `BOKA_DEBUG` environment variable contains any nonempty value. This function also processes the `checkLogin2` authentication response, whose body contains the authenticated session token and apartment identifier. Although the PIN is placed in the HTTPS request body rather than the URL, the resulting session token is subsequently exposed through stderr. Stderr may be captured by terminal recorders, CI systems, agent runtimes, process supervisors, or centr ...[truncated 2064 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never log raw authentication responses. Suppress response-body logging entirely for `checkLogin2` and any other method returning credentials. 2. Implement recursive redaction before logging. At minimum, redact case-insensitive keys such as `Token`, `token`, `pincode`, `pin`, `userid`, `ApartmentID`, and `apartmentnumber`. 3. Prefer an allowlist-based debug format that logs only non-sensitive fields such as the HTTP endpoint hostname, API method, status, error code, and response shape. 4. Parse the debug flag explicitly so only intentional values enable it: ```python DEBUG = os.environ.get("BOKA_DEBUG", "").strip().lower() in {"1", "true", "yes"} ``` 5. Avoid printing complete booking or account response objects when debugging. Apply the same redaction policy to both `_post()` and `_get()` to prevent future endpoints from introducing similar disclosures. 6. Add automated tests that use representative authentication responses and assert that tokens, PINs, apartment identifiers, and user IDs never appear in captured stdout or stderr. 7. Document that debug output is sanitized and ensure operational logging systems apply restricted access, short retention periods, and secret-scanning controls. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill instructs use of a bundled CLI that performs network access to a third-party booking service and reads sensitive credentials from environment variables or local config, yet no explicit permissions are declared. This creates a trust and review gap: the agent may access secrets and external services without the sandbox/policy layer clearly surfacing those capabilities, increasing the risk of unintended data exposure or unauthorized actions on the user's account.

Static analysis

No suspicious patterns detected.