Back to skill

Security audit

new-api-usage

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it handles API keys unsafely by placing them in URLs and allowing unvalidated destinations.

Review before installing. Use this only with a trusted HTTPS new-api endpoint and a narrowly scoped key. Be aware that the usage request places the key in the URL, which may be logged by the destination or infrastructure; the safer design would authenticate only with an Authorization header and reject non-HTTPS base URLs before sending any credential.

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
scripts/query_usage.py:34
Finding
API Key Exposed in URL Query String## Vulnerability Details **File Location**: `scripts/query_usage.py`, lines 34-36 **Vulnerability Type**: Sensitive information transmitted in a query string **Risk Level**: High ### Vulnerable Code ```python def query_usage(base_url: str, api_key: str, timeout: int) -> dict: params = urlencode({"key": api_key}) url = f"{normalize_base_url(base_url)}{LOG_ENDPOINT}?{params}" return request_json(url, api_key, timeout) ``` ### Technical Analysis The API key is included in the request URL as the `key` query parameter. The same credential is also transmitted in the `Authorization` header by `request_json()`, making the query-string transmission redundant where Bearer authentication is supported. URLs are routinely recorded by web servers, reverse proxies, gateways, monitoring systems, browser or network tooling, and access-log aggregation services. Consequently, even when HTTPS protects the request in transit, the complete key may remain stored in logs accessible to operators or other systems. This conflicts with the Skill's stated objective of protecting the full API key and exceeds the minimum data exposure needed for a read-only usage query. ### Attack Path 1. A user invokes the Skill with a valid API key. 2. The script constructs `/api/log/token?key=<API_KEY>`. 3. The request passes through the destination server or an intermediary reverse proxy. 4. The full request URL is retained in an access, telemetry, or diagnostic log. 5. An attacker, unauthorized operator, or compromised logging system retrieves the key. 6. The attacker submits requests using the exposed credential. ### Impact Assessment An exposed key grants the attacker the API permissions assigned to that credential. Depending on server-side authorization, this may include reading quota and usage records or invoking other API functions available to the key. The issue does not directly grant local operating-system privileges, but i ...[truncated 93 chars]
Remediation
## Remediation Suggestions - Remove the API key from the query string and authenticate exclusively through the `Authorization: Bearer` header. - Change the usage request to construct the endpoint without secret parameters: ```python def query_usage(base_url: str, api_key: str, timeout: int) -> dict: url = f"{normalize_base_url(base_url)}{LOG_ENDPOINT}" return request_json(url, api_key, timeout) ``` - If the remote API contract unavoidably requires a query-string key: - Clearly warn users that the destination and its intermediaries may log the credential. - Use a short-lived, read-only, narrowly scoped token. - Configure servers, proxies, observability systems, and error handlers to redact the `key` parameter. - Avoid printing or including complete request URLs in diagnostics. - Prefer changing the server API to accept header-based authentication.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/query_usage.py:16
Finding
API Credential Transmission Without HTTPS Enforcement## Vulnerability Details **File Location**: `scripts/query_usage.py`, lines 16-27 **Vulnerability Type**: Insufficient validation of a credential-bearing network destination **Risk Level**: High ### Vulnerable Code ```python def normalize_base_url(base_url: str) -> str: return base_url.rstrip("/") def request_json(url: str, api_key: str, timeout: int) -> dict: headers = { "Authorization": f"Bearer {api_key}", "Accept": "application/json", } req = Request(url, headers=headers, method="GET") with urlopen(req, timeout=timeout) as response: return json.loads(response.read().decode("utf-8")) ``` ### Technical Analysis The supplied base URL is only normalized by removing trailing slashes. The script does not parse the URL, require the `https` scheme, reject embedded credentials, or constrain the destination before attaching the API key. As a result, a user can accidentally or deceptively be directed to an `http://` endpoint. In that case, the Bearer credential—and, for the usage request, the query-string copy of the credential—is transmitted without TLS confidentiality. Anyone able to observe or alter traffic between the user and destination can capture it. The request implementation also relies on `urlopen()` redirect behavior without an explicit same-origin redirect policy. The script therefore does not itself ensure that credential-bearing requests remain limited to the originally approved origin. Although accepting a user-selected deployment is necessary for the declared functionality, transmitting a secret should be conditioned on secure transport and explicit destination validation. ### Attack Path 1. An attacker persuades a user to supply an `http://` base URL, or the user enters one inadvertently. 2. The script accepts the URL without validation. 3. It attaches the API key as a Bearer credential and sends the request. 4. A network-positioned attacker, malici ...[truncated 785 chars]
Remediation
## Remediation Suggestions - Parse the base URL with `urllib.parse.urlsplit()` and require `https`. - Reject URLs containing embedded usernames or passwords. - Require a non-empty hostname and reject unsupported schemes. - Implement redirect handling that either disables redirects or permits them only when the destination retains the same trusted HTTPS origin. - Perform destination confirmation before sending a credential to an unrecognized host, as required by the Skill documentation. - Consider an explicit allowlist or a user confirmation flag for approved deployment hosts. - Return a clear error before any network request if validation fails. Example validation: ```python from urllib.parse import urlsplit def normalize_base_url(base_url: str) -> str: parsed = urlsplit(base_url) if parsed.scheme.lower() != "https": raise ValueError("--base-url must use HTTPS") if not parsed.hostname: raise ValueError("--base-url must include a valid hostname") if parsed.username is not None or parsed.password is not None: raise ValueError("--base-url must not contain embedded credentials") return base_url.rstrip("/") ``` TLS certificate verification should remain enabled, and certificate-validation failures must never be bypassed automatically.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill enables network access to arbitrary user-supplied endpoints but does not declare any explicit tool scope or permissions boundary. That omission weakens reviewability and enforcement, making it easier for a skill to perform remote requests without clear operator awareness of its network capability.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documented API design sends the secret key as a URL query parameter to `/api/log/token?key={api_key}`, but the skill does not clearly warn users that the key will be transmitted in the request URL. Query-string secrets are commonly exposed through logs, proxies, browser history, monitoring systems, and server access logs, so this can leak credentials beyond the intended recipient.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script appends the API key to the usage-log URL query string while also sending it in the Authorization header. Query-string secrets are commonly exposed through server access logs, reverse proxies, monitoring systems, browser/history tooling, and error messages, creating unnecessary credential leakage risk even if TLS is used.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The tool transmits the API key in the request URL without warning the user, so operators may unknowingly expose the credential to infrastructure that records full URLs. In the context of a skill specifically meant to query quota and usage from arbitrary user-supplied base URLs, this is more dangerous because the user is encouraged to send a sensitive key to potentially untrusted or misconfigured endpoints.

Static analysis

No suspicious patterns detected.