Back to skill

Security audit

TikTok Shop Product Search API

Security checks for vulnerabilities and agentic risk

Overview

This is a focused TikTok Shop product-search API skill that calls a single JustOneAPI endpoint, with a credential-handling caution for the required API token.

Install this only if you are comfortable giving the skill a JustOneAPI token for TikTok Shop product search. Avoid running it in environments that log full command lines or request URLs, keep the token scoped to the minimum access available, and rotate it if you suspect logs may have 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
bin/run.mjs:205
Finding

API Credential Exposed Through Process Arguments and URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:22-30, 110-123, 163-180, 205-215, 238-247; SKILL.md:46, 52
Vulnerability Type: API credential exposure through command-line arguments and URL query parameters
Risk Level: Medium

Vulnerable Code

The operation declares the authentication token as a query parameter:

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

The token is accepted through a command-line 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;
}

It is then inserted 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 query parameters, including the token, are appended to the request URL:

js
function applyQueryParams(operation, params, url) {
  for (const parameter of operation.parameters.filter((item) => item.location === "query")) {

...[truncated 3242 chars]
Remediation
View remediation

Remediation Suggestions

  1. Read the credential directly from the environment inside the Node process instead of accepting it through --token:

    js
    const token = process.env.JUST_ONE_API_TOKEN;
    if (!token) {
      fail("JUST_ONE_API_TOKEN is required.");
    }
    

    Update SKILL.md so the invocation does not contain a token argument:

    bash
    JUST_ONE_API_TOKEN="$JUST_ONE_API_TOKEN" \
      node {baseDir}/bin/run.mjs \
      --operation "searchProductsV1" \
      --params-json '{"keyword":"<keyword>"}'
    
  2. If supported by JustOneAPI, transmit the credential in an authorization header instead of the query string:

    js
    const requestInit = {
      headers: {
        accept: "application/json",
        authorization: `Bearer ${token}`,
      },
      method: operation.method,
    };
    
  3. Remove token from the general parameter object so it cannot be serialized accidentally into URLs, response data, or diagnostic output.

  4. If the upstream API requires query-string authentication, document that residual risk and implement defensive controls:

    • Never print or serialize the complete request URL.
    • Redact token from errors, traces, telemetry, and HTTP logs.
    • Configure proxies and API gateways not to retain sensitive query strings.
    • Use narrowly scoped, short-lived tokens where available.
    • Rotate the token after suspected exposure.
    • Restrict access to process metadata and operational logs.
  5. Add automated tests asserting that credentials never appear in standard output, standard error, diagnostic payloads, or process arguments.

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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill invokes a network-capable helper (node .../bin/run.mjs) that performs authenticated API requests, but the manifest does not declare an explicit tool scope such as permissions or allowed-tools. This creates a policy/visibility gap: an agent platform or reviewer cannot reliably constrain or assess the skill's external communication behavior from the skill declaration alone.

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 an authentication token to be supplied in the URL query string, which is commonly logged by clients, proxies, gateways, browser history, observability tools, and server access logs. Even over HTTPS, query parameters are more likely to be exposed through operational logging and accidental sharing than headers, so this creates unnecessary credential leakage risk.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.secret_argv_exposure

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:45