Back to skill

Security audit

Reddit Keyword Search API

Security checks for vulnerabilities and agentic risk

Overview

The skill is a narrow Reddit search API wrapper, but it exposes the API token through command-line arguments and URL query parameters.

Install only if you are comfortable sending Reddit search keywords and a JustOneAPI token to api.justoneapi.com. Prefer a short-lived, scoped token, avoid sensitive search terms, and rotate the token if it may have appeared in shell history, process telemetry, proxy logs, or API gateway logs.

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:173
Finding

API Token Exposed Through Process Arguments and URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:40-47; bin/run.mjs:25-32, bin/run.mjs:58-64, bin/run.mjs:173-185, and bin/run.mjs:215-225
Vulnerability Type: Credential exposure through command-line arguments and query-string authentication
Risk Level: Medium

The Skill legitimately requires a JustOneAPI credential to perform its declared Reddit keyword search. However, the credential is passed as a command-line argument and then included in the request URL, creating avoidable exposure beyond the minimum necessary for authentication.

Vulnerable Code

The documented invocation passes the secret through the process command line:

bash
node {baseDir}/bin/run.mjs --operation "searchRedditV1" --token "$JUST_ONE_API_TOKEN" --params-json '{"keyword":"<keyword>"}'

The operation declares the token as a query parameter:

js
{
  "defaultValue": null,
  "description": "Access token for this API service.",
  "enumValues": [],
  "location": "query",
  "name": "token",
  "required": true,
  "schemaType": "string"
}

The CLI 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;
}

All parameters declared with location === "query", including the token, are 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)
...[truncated 2692 chars]
Remediation
View remediation

Remediation Suggestions

  1. Read the credential directly from process.env.JUST_ONE_API_TOKEN instead of requiring it through --token. This prevents routine exposure through process argument inspection:

    js
    const token = process.env.JUST_ONE_API_TOKEN;
    if (!token) {
      fail("JUST_ONE_API_TOKEN is required.", {
        operationId: operation.operationId,
      });
    }
    
  2. Prefer an authorization header if supported by JustOneAPI:

    js
    const requestInit = {
      headers: {
        accept: "application/json",
        authorization: `Bearer ${token}`,
      },
      method: operation.method,
    };
    
  3. Remove the token from the operation's query parameters when header-based authentication is available. Do not permit users to supply token inside --params-json.

  4. If the backend only supports query-string authentication, request or implement a header-based authentication option. Until then:

    • Never print or serialize the complete request URL.
    • Configure proxies, API gateways, and observability systems to redact the token query parameter.
    • Avoid including URLs containing credentials in exceptions or debug output.
    • Use short-lived, narrowly scoped tokens where supported.
    • Disable unnecessary request and command-line telemetry.
  5. Update SKILL.md so the recommended invocation relies on the environment variable without expanding it into a command-line argument.

  6. Rotate any token that may already have been retained in process telemetry, shell history, gateway logs, or monitoring systems.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill defines the access token as a query parameter and later appends all query parameters directly to the URL, which causes the credential to be transmitted in the request URI. Secrets in URLs are commonly exposed through logs, browser/history equivalents, reverse proxies, monitoring systems, and error telemetry, making credential leakage substantially more likely than if the token were sent in a header.

Content

Scanner excerpt · bin/run.mjs (reported line 20)May include surrounding context.

js
"parameters": [
        {
          "defaultValue": null,
          "description": "Access token for this API service.",
          "enumValues": [],
          "location": "query",
          "name": "token",

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The presence of a required access token parameter indicates the skill handles credentials directly, and in this manifest that credential is passed as user-supplied query input. In the context of an agent skill, this is more dangerous because secrets may be surfaced to the model, stored in traces, or propagated to third-party infrastructure during normal operation.

Content

Scanner excerpt · generated/operations.json (reported line 15)May include surrounding context.

json
"parameters": [
        {
          "defaultValue": null,
          "description": "Access token for this API service.",
          "enumValues": [],
          "location": "query",
          "name": "token",

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill requires an access token to be sent in the URL query string, which is commonly logged by clients, proxies, gateways, browser history, and observability systems. This creates a substantial risk of credential leakage and replay, especially because the manifest provides no warning or safer authentication mechanism.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

Requiring an access token in the query string is a genuine credential-handling vulnerability. Query parameters are commonly recorded in server logs, intermediary proxies, analytics tools, and referrer data, so a leaked token could enable unauthorized use of the API service.

Content

Scanner excerpt · generated/operations.md (reported line 19)May include surrounding context.

md
| Name | In | Required | Type | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `token` | `query` | yes | `string` | n/a | Access token for this API service. |
| `keyword` | `query` | yes | `string` | n/a | Search query keywords. |
| `after` | `query` | no | `string` | n/a | Pagination token to retrieve the next set of results. |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill invokes a Node helper that performs outbound API calls using a bearer token, but the manifest does not declare any explicit tool scope such as allowed network access or permissions. This creates a transparency and policy-enforcement gap: a host may permit the skill without clearly understanding that it can make external requests and transmit user-supplied data and secrets to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code performs an outbound HTTP request using query parameters populated from keyword and token, which sends user/system data to an external service. There is no confirmation prompt, user-facing log/print, or inline warning/comment disclosing that the skill will transmit these values off-host.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This JSON manifest describes the skill's purpose and operation, but it does not specify any concrete trigger phrases, activation conditions, or exclusion conditions. For manifest files, this can make invocation behavior ambiguous because there is no clear boundary for when the skill should or should not be selected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation describes sending both a search keyword and an access token to an external API endpoint but does not warn users that their inputs and credentials are transmitted off-platform. This is a real transparency and privacy issue because users may unknowingly submit sensitive search terms, and placing the token in the query string increases exposure through logs, browser history, proxies, and monitoring systems.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.