Back to skill

Security audit

TikTok User Published Posts API

Security checks for vulnerabilities and agentic risk

Overview

This skill is a narrow JustOneAPI helper for one TikTok published-posts endpoint, with a real but disclosed API-token handling caveat.

Before installing, understand that your JustOneAPI token will be used to call api.justoneapi.com and may appear in command-line process metadata or service-side URL logs because this helper passes it as a CLI argument and query parameter. Use a scoped token if available and rotate it if you suspect it was logged.

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

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

Content
View full analysis

Vulnerability Details

File Location: bin/run.mjs:18-27, bin/run.mjs:73-86, bin/run.mjs:241-251, and SKILL.md:45-50
Vulnerability Type: API credential exposure
Risk Level: Medium

Vulnerable Code

bin/run.mjs:18-27 defines the API token as a query parameter:

javascript
{
  "defaultValue": null,
  "description": "Security token for API access.",
  "enumValues": [],
  "location": "query",
  "name": "token",
  "required": true,
  "schemaType": "string"
},

bin/run.mjs:73-86 injects the supplied token into the parameter collection and subsequently constructs the request URL:

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

bin/run.mjs:241-251 serializes every query parameter, including the API token, into the URL:

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

SKILL.md:45-50 instructs users to expose the token as a command-line argument:

bash
node {baseDir}/bin/run.mjs --operation "getUserPostV1" --token "$JUST_ONE_API_TOKEN" --params-json '{"secUid":"<secUid>"}'
markdown
- Required: `JUST_ONE_API_TOKEN`
- Pass the token with `--token "$JUST_ONE_API_TOKEN"`; do not paste token values into chat messages, screenshots, or logs.

Technical Analysis

...[truncated 2860 chars]

Remediation
View remediation

Remediation Suggestions

  1. Use authorization headers where supported. Remove the token from the operation's query-parameter definition and transmit it through an authentication header, for example:

    javascript
    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}`,
      },
    };
    

    Use the exact authentication scheme required by the upstream API.

  2. Read the credential directly from the environment. Remove or deprecate --token so the secret is not placed in the process argument vector. If interactive input is required, obtain it through a non-echoing input mechanism rather than a command-line argument.

  3. Prevent token injection through general parameters. Reject token inside --params-json; otherwise callers could still place the credential into the generated URL after command-line token support is removed.

  4. Redact secrets defensively. Ensure request URLs, exceptions, debug output, telemetry, and backend error payloads never expose token, authorization, or equivalent sensitive values.

  5. If query authentication is mandatory upstream, read the token directly from the environment, document the residual URL-logging risk, disable or redact query-string logging across proxies and monitoring systems, use narrowly scoped short-lived credentials, and rotate any token suspected of having been logged.

  6. Update the documentation. Replace the --token "$JUST_ONE_API_TOKEN" example with an environment-based invocation that does not expose the credential through command-line arguments.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script injects a required security token into query parameters and then sends it in the outbound HTTP request, but there is no confirmation prompt, user-facing log, or explanatory comment/docstring warning that credential-like data will be transmitted to a third-party API. Because this code handles and transmits sensitive access material, it meets the missing-warning criteria for code files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This manifest presents all user-facing natural-language fields, including description, display name, summary, and parameter descriptions, only in English with no indication of locale choice or opt-in. Under the policy rule for language or locale constraints, this is a natural-language policy issue because the skill implicitly fixes one language for all users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.