Back to skill

Security audit

Douyin (TikTok China) User Published Videos API

Security checks for vulnerabilities and agentic risk

Overview

This is a narrow JustOneAPI wrapper for one Douyin video-list endpoint, with a real token-handling hygiene risk but no evidence of hidden, destructive, persistent, or purpose-mismatched behavior.

Install only if you trust JustOneAPI with the token and requested Douyin lookup data. Use a least-privilege, revocable token if available, avoid sharing command lines or logs from runs, and rotate the token if you suspect process telemetry or URL logs captured it.

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

API Token Exposed Through Process Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:138-141; documented invocation at SKILL.md:38
Vulnerability Type: API credential exposure through process arguments
Risk Level: Medium

Vulnerable Code

SKILL.md:38:

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

bin/run.mjs:138-141:

js
if (flag === "--token") {
  parsed.token = value;
  index += 1;
  continue;
}

Technical Analysis

The documented execution method expands JUST_ONE_API_TOKEN into the Node.js process command line. Although the token originates in an environment variable, passing it through --token causes the secret value to become part of the process argument vector.

Depending on operating-system configuration and local access controls, command-line arguments may be visible to other local users, process-monitoring software, audit agents, crash diagnostics, or orchestration telemetry. The implementation does not print the token directly, but accepting it through a command-line flag unnecessarily expands its exposure surface.

This behavior is not required for the Skill's declared functionality. The runner can read process.env.JUST_ONE_API_TOKEN directly without placing the credential in process arguments.

Attack Path

  1. A user invokes the Skill using the documented command.
  2. The shell expands $JUST_ONE_API_TOKEN into the value supplied to --token.
  3. The secret appears in the Node.js process argument vector while the process is running.
  4. A local user or monitoring component with permission to inspect process metadata captures the arguments.
  5. The observer extracts the API token and reuses it against JustOneAPI.

Exploitation requires local process-observation access or access to telemetry that records command-line arguments.

Impact Assessment

Successful exploitation discloses t ...[truncated 418 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove support for supplying credentials through --token.

  • Read the credential directly from the declared environment variable:

    js
    const token = process.env.JUST_ONE_API_TOKEN;
    if (!token) {
      fail("JUST_ONE_API_TOKEN is required.", {
        operationId: operation.operationId,
      });
    }
    
  • Update SKILL.md so the command does not interpolate the token:

    bash
    node {baseDir}/bin/run.mjs --operation "getUserVideoListV3" --params-json '{"secUid":"<secUid>"}'
    
  • Ensure diagnostic and error-reporting systems do not capture credential-bearing environment variables.

  • Rotate the token if commands containing it may already have been collected in process telemetry or shell execution logs.

  • Prefer short-lived, narrowly scoped credentials where supported by the service.

T09 · Insecure Skill Coding Practices

Warning
Location
bin/run.mjs:17
Finding

API Token Transmitted as a URL Query Parameter

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:17-25, bin/run.mjs:76-78, and bin/run.mjs:223-230
Vulnerability Type: Sensitive credential exposure in request URLs
Risk Level: Medium

Vulnerable Code

bin/run.mjs:17-25 defines 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"
},

bin/run.mjs:76-78 applies all query parameters to the URL:

js
applyPathParams(operation, params, url);
applyQueryParams(operation, params, url);

bin/run.mjs:223-230 serializes the token and other query values into 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);
  }
}

Technical Analysis

The runner classifies the API token as a query parameter and appends it to the HTTPS request URL. TLS protects the request from ordinary network interception while it is in transit, but it does not prevent the complete URL from being recorded at either endpoint or by trusted infrastructure.

URLs are commonly captured by reverse-proxy access logs, API gateways, observability platforms, error telemetry, request tracing, and debugging tools. Consequently, query-string authentication can disclose the credential to systems and personnel that do not need access to it.

Sending an authentication credential to the declared JustOneAPI host is necessary for the advertised API operation. However, placing that credential in the URL is a broader exposure mechanism than header-based authentication. The destination is fixed to https://api.justoneapi.com; ...[truncated 1227 chars]

Remediation
View remediation

Remediation Suggestions

  • Prefer an authentication header rather than a URL parameter, subject to upstream API support:

    js
    const requestInit = {
      method: operation.method,
      headers: {
        accept: "application/json",
        authorization: `Bearer ${token}`,
      },
    };
    
  • Do not add token to url.searchParams when header-based authentication is available.

  • If JustOneAPI strictly requires query-string authentication:

    • Confirm and document that requirement.
    • Configure clients, proxies, gateways, and observability systems to redact the token query parameter.
    • Never include the complete request URL in errors or debug logs.
    • Use short-lived, least-privilege tokens and enforce appropriate rate and spending limits.
    • Rotate credentials after suspected log exposure.
  • Add automated tests verifying that secrets do not appear in process arguments, standard output, standard error, or captured request logs.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill explicitly requests an access token and places it in a query parameter, which can enable credential exposure and reuse if captured from logs, telemetry, caches, or shared infrastructure. Because the token grants access to the upstream API service, compromise could allow unauthorized API use, data access, quota abuse, or account/billing impact.

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",

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 this API service. |
| `secUid` | `query` | yes | `string` | n/a | The unique user ID (sec_uid) on Douyin. |
| `maxCursor` | `query` | no | `integer` | `0` | Pagination cursor; use 0 for the first page, and the `max_cursor` from the previous response for subsequent pages. |

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 this API service. |
| `secUid` | `query` | yes | `string` | n/a | The unique user ID (sec_uid) on Douyin. |
| `maxCursor` | `query` | no | `integer` | `0` | Pagination cursor; use 0 for the first page, and the `max_cursor` from the previous response for subsequent pages. |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes a network-capable helper (node {baseDir}/bin/run.mjs) that sends user-supplied parameters and an API token to an external service, but it does not declare an explicit tool/network permission boundary. Missing scope declarations weaken reviewability and enforcement, so an agent platform may allow broader outbound access than users or policy expect. In this context, the skill is specifically designed to call a remote API, which makes the omission more meaningful rather than theoretical.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code performs an outbound HTTP request and includes a required token query parameter, which is sensitive authentication data. The file provides error output but no confirmation prompt, user-facing notice, or explanatory comment/docstring warning that credentials will be sent to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The operation requires an access token to be sent in the URL query string, which is commonly exposed through server logs, browser history, monitoring tools, referrer leakage, and intermediary infrastructure. Even if HTTPS is used, query parameters are more broadly retained and disclosed than headers, so this creates unnecessary credential exposure without any warning to the user.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.