Back to skill

Security audit

Bilibili Video Details API

Security checks for vulnerabilities and agentic risk

Overview

This is a narrow JustOneAPI helper for fetching Bilibili video details, with a credential-handling caveat but no evidence of hidden, destructive, or unrelated behavior.

Install only if you are comfortable sending Bilibili video IDs and a JustOneAPI token to api.justoneapi.com. Use a limited, revocable token if possible, avoid logging full command lines or request URLs, and rotate the token if you suspect it appeared in 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:221
Finding

API Access Token Exposed Through URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs, lines 24–31, 64–67, and 221–229
Vulnerability Type: Credential exposure through URL query parameters
Risk Level: Medium

Vulnerable Code

The operation manifest defines the access token as a query parameter:

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

The token is injected into the parameter collection before 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);

The query-parameter sink converts the token to a string and appends it directly to the URL:

js
function appendValue(searchParams, name, value) {
  if (Array.isArray(value)) {
    for (const item of value) {
      appendValue(searchParams, name, item);
    }
    return;
  }
  if (value && typeof value === "object") {
    searchParams.append(name, JSON.stringify(value));
    return;
  }
  searchParams.append(name, String(value));
}

Technical Analysis

injectToken() places the JustOneAPI credential in params.token. Because the manifest declares token with location: "query", applyQueryParams() ultimately passes it to appendValue(), producing a request URL equivalent to:

text
https://api.justoneapi.com/api/bilibili/get-video-detail/v2?token=<secret>&bvid=<video-id>

HTTPS protects the request from passive interception while it is in transit, but it does not prevent the complete URL from being retaine ...[truncated 2291 chars]

Remediation
View remediation

Remediation Suggestions

  1. Change the API authentication contract to accept the token in a request header, preferably:

    js
    const requestInit = {
      headers: {
        "accept": "application/json",
        "authorization": `Bearer ${args.token}`,
      },
      method: operation.method,
    };
    
  2. Remove token from the operation's query-parameter definitions and ensure applyQueryParams() can never serialize authentication credentials.

  3. Reject token inside --params-json so callers cannot bypass the protected authentication path.

  4. Update generated/operations.json, generated/operations.md, and SKILL.md to document header-based authentication.

  5. Configure API gateways, reverse proxies, backend servers, and observability systems to redact existing token query parameters while compatibility with the old API remains necessary.

  6. Avoid logging complete request URLs or command-line arguments containing secrets.

  7. Rotate tokens that may already have been retained in URL logs and apply short expiration periods and least-privilege scopes.

  8. Add automated tests asserting that serialized request URLs never contain the token value.

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 (7)

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The API requires an access token to be passed as a query parameter, which is an unsafe credential-handling pattern. Query parameters are commonly exposed in logs, browser history, proxy records, analytics systems, and referrer data, increasing the chance of credential leakage and unauthorized API use.

Content

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

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

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

js
| Name | In | Required | Type | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `token` | `query` | yes | `string` | n/a | Access token for the API. |
| `bvid` | `query` | yes | `string` | n/a | Bilibili Video ID (BVID). |

### Request body

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

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 the API. |
| `bvid` | `query` | yes | `string` | n/a | Bilibili Video ID (BVID). |

### Request body

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill invokes a network-capable helper (node {baseDir}/bin/run.mjs) that sends requests to an external API, but the manifest does not declare an explicit tool scope such as permissions or allowed-tools. This weakens least-privilege controls and makes it harder for a host platform or reviewer to understand and constrain what the skill is allowed to do, increasing the risk of unintended outbound requests or misuse if the helper behavior changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill explicitly defines the API access token as a query parameter and later appends all query parameters into the URL. Query-string credentials are routinely exposed through logs, proxies, browser/history artifacts, monitoring systems, and error messages, so this increases the chance of accidental token disclosure even when HTTPS is used.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This JSON skill definition describes the API operation and purpose, but it does not define any explicit trigger phrases, activation constraints, or exclusion conditions. For manifest files, the absence of specific invocation scope can make it unclear when the skill should activate versus when it should not.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
36% confidence
Finding

The file's natural-language descriptions are written in English, but they do not explicitly instruct users to use English or prohibit other locales. Because there is no clear language-forcing policy text, this does not rise to a confident policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.