Back to skill

Security audit

Zhihu API

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent read-only Zhihu API skill, but its token handling may expose the JustOneAPI credential in process listings or URL logs.

Install only if you are comfortable giving this skill a JustOneAPI token for Zhihu data retrieval. Prefer a narrowly scoped token if available, avoid running it where command arguments or full URLs are logged, and rotate the token if you suspect exposure.

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

API Credential Exposed Through Command-Line Arguments and URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:216-232, bin/run.mjs:350-370, and bin/run.mjs:382-390; invocation documented at SKILL.md:42
Vulnerability Type: API credential exposure through process metadata and URL query strings
Risk Level: Medium

Vulnerable Code

At bin/run.mjs:216-232, the supplied token is injected into the operation parameters, after which all query parameters are added to the request URL:

js
const params = parseParams(args.paramsJson);
applyDefaults(operation, params);
injectToken(operation, params, args.token);
validateRequired(operation, params);

const baseUrl = manifest.baseUrl;
const url = new URL(operation.path, ensureBaseUrl(baseUrl));
applyPathParams(operation, params, url);
applyQueryParams(operation, params, url);

const requestInit = {
  headers: {
    "accept": "application/json",
  },
  method: operation.method,
};

At bin/run.mjs:350-370, the credential is assigned to params.token, while the manifest defines token as a query parameter:

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

function validateRequired(operation, params) {
  const missing = [];
  for (const parameter of operation.parameters) {
    if (parameter.required && params[parameter.name] === undefined) {
      missing.push(parameter.name);
    }
  }

At bin/run.mjs:382-390, every parameter whose manifest location is query, including token, is appended to the URL:

js
function applyQueryParams(operation, params, url) {
  for (const parameter of operation.parameters.filter((item) => item.locati
...[truncated 3436 chars]
Remediation
View remediation

Remediation Suggestions

  1. Read the token directly from process.env.JUST_ONE_API_TOKEN rather than requiring a --token command-line argument.
  2. Send the credential in an authentication header supported by the service, preferably:
    js
    const token = process.env.JUST_ONE_API_TOKEN;
    if (!token) {
      fail("JUST_ONE_API_TOKEN is required.");
    }
    
    const requestInit = {
      method: operation.method,
      headers: {
        accept: "application/json",
        authorization: `Bearer ${token}`,
      },
    };
    
  3. Remove token from the operation query-parameter definitions and explicitly prevent callers from supplying params.token.
  4. Update SKILL.md so documented commands do not include credentials in command-line arguments.
  5. If JustOneAPI only supports query-string authentication, document that constraint and implement compensating controls:
    • Read the token only from the environment.
    • Disable or redact query-string logging in clients, gateways, proxies, monitoring systems, and server access logs.
    • Ensure errors never print the complete request URL.
    • Use narrowly scoped, short-lived tokens where supported.
    • Rotate tokens regularly and immediately after suspected exposure.
    • Restrict access to process telemetry and infrastructure logs.
  6. Add automated tests confirming that secrets never appear in command arguments, standard output, standard error, exception details, or logged URLs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • 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 (9)

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

md
- Get a token from [Just One API Dashboard](https://dashboard.justoneapi.com/en/login?utm_source=clawhub.ai&utm_medium=referral&utm_campaign=justoneapi_zhihu&utm_content=project_link).
- Authentication details: [Just One API Usage Guide](https://docs.justoneapi.com/en/?utm_source=clawhub.ai&utm_medium=referral&utm_campaign=justoneapi_zhihu&utm_content=project_link).

## Output Rules

- Lead with the concrete Zhihu result: matched topic, answer feed insight, article detail, or column update.
- For keyword search, restate the keyword and offset before summarizing the most relevant matches.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to run a Node helper that performs authenticated network requests, but the manifest does not declare any explicit tool scope such as allowed tools or permissions. This creates an authorization boundary gap: a host may permit broader execution or networking than intended, making review and enforcement harder and increasing the chance of unintended external access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill requires a sensitive token as a query parameter and then appends all query parameters to the URL before issuing the request. Query-string secrets are routinely exposed in logs, proxies, browser/history equivalents, monitoring systems, and upstream infrastructure, making accidental credential disclosure more likely than if the token were sent in an Authorization header.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The API requires a sensitive token to be sent in the URL query string, which is commonly logged by clients, proxies, gateways, browser history, and observability tooling. This increases the likelihood of credential exposure and replay, especially because the skill calls an external third-party API and the manifest provides no warning or safer authentication mechanism.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The operation documentation requires a sensitive token to be sent as a URL query parameter, which is commonly exposed through logs, browser history, proxy telemetry, analytics, and referrer leakage. Even if transport uses HTTPS, query strings are often captured by infrastructure components, so documenting this pattern without warning or safer alternatives normalizes credential exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This endpoint repeats the same insecure pattern of requiring a token in the query string, again without any warning about exposure risk. Repetition across endpoints increases the chance that client implementations, examples, and downstream tooling will propagate unsafe credential handling broadly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documented API continues to require credential transmission in the URL, which can leak through standard operational channels even when users are not explicitly misusing the API. Because this is a content collection/monitoring workflow, requests may be automated at scale, increasing the volume of leaked secrets if logging or observability systems capture full URLs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The search endpoint also places the required token in the query string with no security warning, creating the same credential leakage risk as the other operations. Search requests are especially likely to pass through user-facing tools, debugging consoles, and analytics systems, which further raises the likelihood of accidental disclosure.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This is a .json manifest file, so vague-trigger review applies. The top-level description states general-purpose actions like "Search" and "track" without any explicit invocation boundaries, excluded contexts, or a narrow trigger scope, which can increase the chance of unintended invocation in systems that rely on manifest descriptions.

Content

No source excerpt is available for this finding.