Back to skill

Security audit

Wakapi Query

Security checks for vulnerabilities and agentic risk

Overview

This is a read-only Wakapi stats helper, but users should configure it with HTTPS because it sends the API key in an Authorization header.

Install only if you trust the Wakapi instance you configure. Use an HTTPS WAKAPI_URL whenever possible, avoid pasting WAKAPI_API_KEY into chat or shared logs, and understand that the skill can read coding activity metadata available to that API key.

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/wakapi_query.py:47
Finding

Wakapi API Key May Be Transmitted over Plaintext HTTP

Content
View full analysis
str: u = url.strip().rstrip("/") if not u: raise SystemExit( "WAKAPI_URL is required for the Wakapi skill. " "Example: export WAKAPI_URL=https://wakapi.example.com" ) return u ``` ```python def _auth_basic_value(api_key: str) -> str: if not api_key: raise SystemExit("WAKAPI_API_KEY is empty") b64 = base64.b64encode(api_key.encode("utf-8")).decode("ascii") return f"Basic {b64}" def _request_headers() -> dict[str, str]: key = os.environ.get("WAKAPI_API_KEY", "") if not key: raise SystemExit("WAKAPI_API_KEY is empty") return {"Authorization": _auth_basic_value(key), "Accept": "application/json"} def _get_json( url: str, headers: dict[str, str], *, timeout: float | None = None, ) -> tuple[int, Any]: t = _resolve_http_timeout(cli_sec=timeout, fallback_sec=60) _log_request("GET", url) req = urllib.request.Request(url, method="GET", headers=headers) try: with urllib.request.urlopen(req, timeout=t) as resp: body = resp.read().decode("utf-8") ``` The project documentation explicitly permits plaintext HTTP: ```markdown | **Network** | Outbound **HTTPS** (or `http://` if your instance uses it) to **`WAKAPI_URL`**. | ``` ### Technical Analysis The URL normalization routine only removes surrounding whitespace and trailing slashes. It does not parse the URL or enforce HTTPS before authenticated requests are made. Authenticated subcommands read `WAKAPI_API_KEY`, encode it using Base64, and place it directly in an HTTP Basic Authorization header. Base64 provides no confidentiality and can be ...[truncated 1794 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (4)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
scripts/wakapi_query.py). Run from the **skill root** (directory that contains `SKILL.md`). |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation indicates it requires both environment access and outbound network access, but it does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch can cause the agent platform to grant broader capabilities than users expect, increasing the risk of secret exposure or unintended network requests when the skill is invoked.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/wakapi-api.md (reported line 71)May include surrounding context.

md
| **`stats <range>`** | **Path** after `/stats/` | `today`, `yesterday`, `week`, `month`, `year`, `last_7_days`, `last_30_days`, `last_6_months`, `last_year`, `all_time`, … — see [compat stats handler](https://github.com/muety/wakapi/blob/master/routes/compat/wakatime/v1/stats.go) / `interval.go` |
| **`summaries`** | **Query** `range=…` **or** `start`+`end` | Same **interval aliases** as presets, **or** explicit **`YYYY-MM-DD`** dates |

Do not assume a **`summaries`** preset string works as a **`stats`** path segment without checking (and vice versa).

**`stats` CLI flags:**

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file documents setting WAKAPI_API_KEY and later shows curl commands that derive and send the credential in a Basic Authorization header. While the skill is read-only, the description does not include any warning that the commands handle sensitive credentials or that shell history/process visibility considerations may apply.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.