Back to skill

Security audit

IMDb Streaming Picks API

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it handles the required API token in ways that can expose it through process listings or URL logs.

Review this before installing if your JustOneAPI token has paid quota, broad account access, or sensitive usage implications. The endpoint scope is narrow and no malicious behavior was found, but tokens passed on the command line or in query strings may appear in local process metadata, shell traces, service logs, proxy logs, or API logs. Prefer a version that reads the token from a protected environment variable and sends it in an authorization header if the provider supports that.

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
bin/run.mjs:187
Finding
API Token Exposed Through Process Arguments and URL Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:42,50`; `bin/run.mjs:22,81-100,149-159,187-198,230-237`; `generated/operations.json:13-24`; `generated/operations.md:13-18` **Vulnerability Type**: Credential exposure through command-line arguments and URL query parameters **Risk Level**: Medium ### Vulnerable Code The documented invocation expands the secret into a command-line argument: ```bash node {baseDir}/bin/run.mjs --operation "streamingPicksQuery" --token "$JUST_ONE_API_TOKEN" --params-json '{"key":"value"}' ``` The token is defined as a query parameter: ```js { "defaultValue": null, "description": "User's authentication token.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" } ``` The argument parser reads the token from the process command line: ```js if (flag === "--token") { parsed.token = value; index += 1; continue; } ``` The token is copied into the request parameters: ```js function injectToken(operation, params, cliToken) { const tokenParam = operation.parameters.find((parameter) => parameter.name === "token"); if (!tokenParam || params.token !== undefined) { return; } if (!cliToken) { fail("--token is required for this operation.", { operationId: operation.operationId, }); } params.token = cliToken; } ``` Every parameter marked as a query parameter, including the token, is appended to the URL: ```js function applyQueryParams(operation, params, url) { for (const parameter of operation.parameters.filter((item) => item.location === "query")) { const value = params[parameter.name]; if (value === undefined) { continue; } appendValue(url.searchParams, parameter.name, value); } } ``` The resulting URL is sent directly: ```js const baseUrl = manifest.baseUrl; const url = new URL(operation.path, ensureBaseUrl(baseUrl)); applyPathParams(operation, params, url); applyQueryParams(operation, params, url); ...[truncated 2895 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Remove command-line token handling** - Read the token directly from `process.env.JUST_ONE_API_TOKEN`. - Remove support for `--token` so the secret is not included in the process argument vector. - Fail safely when the environment variable is absent without printing its value. 2. **Use an authorization header** - Update the API contract to use an appropriate header, such as: ```js const token = process.env.JUST_ONE_API_TOKEN; if (!token) { fail("JUST_ONE_API_TOKEN is required.", { operationId: operation.operationId, }); } const requestInit = { headers: { accept: "application/json", authorization: `Bearer ${token}`, }, method: operation.method, }; ``` - Confirm the exact authentication scheme supported by JustOneAPI before deployment. - If the service only supports query authentication, request a header-based authentication option from the provider and document the residual logging risk until migration is possible. 3. **Prevent accidental query injection** - Remove `token` from the operation's query-parameter definition. - Reject `token` if supplied through `--params-json`, preventing callers from bypassing the safer credential path. 4. **Harden request behavior** - Avoid forwarding authorization credentials across cross-origin redirects. - Prefer disabling redirects or validate every redirect destination against the expected HTTPS origin. - Ensure errors, telemetry, and debug output redact authorization headers and token-like query parameters. 5. **Update generated artifacts and documentation** - Regenerate `generated/operations.json` and `generated/operations.md` after changing the authentication model. - Replace the documented command with one that relies on the environment variable without shell expansion into arguments: ```bash JUST_ONE_API_TOKEN="..." node {baseDir}/bin/run.mjs \ --operation "streamingPicksQuery" \ --params-json '{"languageCountry" ...[truncated 293 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill requires the authentication token to be sent as a URL query parameter, which is commonly exposed through logs, browser/history layers, proxy infrastructure, monitoring tools, and error reporting systems. Although the request uses HTTPS, placing secrets in the URL materially increases accidental credential disclosure risk compared with using an Authorization header or other secret-bearing header.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The API requires an authentication token to be passed in the URL query string, which is a well-known unsafe pattern because query parameters are commonly recorded in browser history, reverse proxies, server access logs, analytics tooling, and monitoring systems. In this skill context, the token is a credential for a third-party API, so exposure could allow unauthorized reuse of the account or API quota by anyone who obtains the logged URL.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
The manifest sets `languageCountry` to `en_US` by default, which imposes a specific language/locale choice when the user does not provide one. Although other locales are available, the file does not indicate user opt-in before applying the English (US) default.

Static analysis

No suspicious patterns detected.