Back to skill

Security audit

Douyin Creator Marketplace (Xingtu) Follower Distribution API

Security checks for vulnerabilities and agentic risk

Overview

The skill is a narrow JustOneAPI wrapper, but it handles the user's API token in ways that can expose it through URLs and process arguments.

Review this before installing if the JustOneAPI token has paid quota or broad account access. Use a narrowly scoped token if possible, avoid environments that log full command lines or URLs, and rotate the token if it may have appeared in process telemetry, proxy logs, or request 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
bin/run.mjs:219
Finding

API Authentication Token Exposed in the Request URL

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:89-96, 219-227
Vulnerability Type: Authentication token disclosure through a URL query parameter
Risk Level: Medium

Vulnerable Code

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);
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 operation manifest explicitly defines the authentication token as a query parameter:

js
{
  "defaultValue": null,
  "description": "User authentication token.",
  "enumValues": [],
  "location": "query",
  "name": "token",
  "required": true,
  "schemaType": "string"
}

Technical Analysis

The helper injects the API token into the general parameter object and passes every parameter whose location is query to URLSearchParams. Consequently, the final request URL contains the credential in the form ?token=....

HTTPS protects the URL from passive observation while it is transmitted to the fixed destination, https://api.justoneapi.com. However, query strings are commonly captured by reverse-proxy access logs, API gateways, network monitoring products, tracing systems, diagnostic tooling, and backend request logs. Such systems may retain the complete URL for substantially longer than the request itself.

Sending authentication material to the declared API provider is necessary for the Skill's functionality. ...[truncated 1424 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace query-string authentication with a provider-supported HTTP authentication header, preferably:

    js
    const requestInit = {
      headers: {
        accept: "application/json",
        authorization: `Bearer ${token}`,
      },
      method: operation.method,
    };
    
  2. Remove token from the operation's query-parameter definitions so the generic query builder cannot append it to the URL.

  3. Keep authentication material in a separate variable rather than merging it into the general user-supplied parameter object.

  4. If the upstream API only accepts query authentication, request a header-based authentication mechanism from the provider. Until then:

    • Configure gateways, proxies, and telemetry systems to redact the token parameter.
    • Disable complete-URL logging for this endpoint.
    • Apply short token lifetimes and narrowly scoped permissions.
    • Rotate the token immediately if it may have entered logs.
  5. Add automated tests asserting that serialized request URLs never contain token values.

T09 · Insecure Skill Coding Practices

Note
Location
bin/run.mjs:146
Finding

API Token Exposed Through Process Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:40-48; bin/run.mjs:146-165
Vulnerability Type: Secret exposure through the process argument vector
Risk Level: Low

Vulnerable Code

The documented invocation expands the environment variable into a command-line argument:

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

The executable accepts and stores the resulting argument:

js
function parseArgs(argv) {
  const parsed = { operation: null, paramsJson: "{}", token: null };
  for (let index = 0; index < argv.length; index += 1) {
    const flag = argv[index];
    const value = argv[index + 1];
    if (flag === "--operation") {
      parsed.operation = value;
      index += 1;
      continue;
    }
    if (flag === "--params-json") {
      parsed.paramsJson = value;
      index += 1;
      continue;
    }
    if (flag === "--token") {
      parsed.token = value;
      index += 1;
      continue;
    }
    fail(`Unknown argument "${flag}".`);
  }
  return parsed;
}

Technical Analysis

Although the token originates in the JUST_ONE_API_TOKEN environment variable, the documented shell command expands it into --token VALUE. This places the credential in the process argument vector.

Depending on the operating system and deployment environment, command-line arguments may be visible through process-inspection utilities, /proc interfaces, container or orchestration metadata, endpoint monitoring products, crash reports, audit systems, or process-launch telemetry. Access is generally constrained by operating-system permissions, making this lower risk than unrestricted disclosure, but command-line arguments are not an appropriate secret-transport mechanism.

The code does not print the token directly to standard output or standard error. The exposure exists ...[truncated 1113 chars]

Remediation
View remediation

Remediation Suggestions

  1. Read the token directly from the environment instead of accepting it through --token:

    js
    const token = process.env.JUST_ONE_API_TOKEN;
    if (!token) {
      fail("JUST_ONE_API_TOKEN is required.");
    }
    
  2. Update the documented invocation so it does not expand the secret into the command line:

    bash
    node {baseDir}/bin/run.mjs --operation "getKolFansDistributionV1" --params-json '{"kolId":"<kolId>"}'
    
  3. Remove or deprecate the --token option. If compatibility requires retaining it temporarily, prefer the environment variable and emit a warning without including the supplied value.

  4. For managed deployments, use a secret manager or protected file descriptor rather than process arguments.

  5. Ensure process-launch telemetry, crash reporting, and audit logging redact authentication-related arguments.

  6. Rotate any token known to have been captured in process telemetry or diagnostic records.

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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill invokes a network-capable helper (node .../bin/run.mjs) and is explicitly designed to call a remote API, but it does not declare any permissions or allowed-tools scope. This creates a mismatch between documented behavior and enforceable controls, making it easier for the skill to perform external requests without transparent policy gating or least-privilege review.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill defines the authentication token as a query parameter and injects it into the request URL, which causes the secret to appear in URLs. Query-string credentials are commonly exposed through logs, browser/history records, proxies, monitoring tools, and referrer leakage, making accidental credential disclosure materially more likely even when HTTPS is used.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The operation requires an authentication token to be sent in the URL query string, which is commonly logged by clients, proxies, gateways, browser history, and server access logs. Even over HTTPS, query parameters have broader exposure than headers, so token leakage can enable unauthorized API access and account misuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The API documentation instructs callers to send the authentication token in the URL query string, which is commonly logged by browsers, proxies, web servers, analytics tools, and monitoring systems. This increases the chance of credential leakage through logs, referrers, shared URLs, or debugging output, especially in an agent/integration context where requests may be broadly instrumented.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.