Back to skill

Security audit

Twitter User Published Posts API

Security checks for vulnerabilities and agentic risk

Overview

The skill is narrowly built for one JustOneAPI Twitter-posts endpoint, but it handles the API token in a way that can expose it through command arguments and URL query strings.

Review before installing. Use it only if you are comfortable sending a JustOneAPI token and queried Twitter user IDs to JustOneAPI. Prefer a revised version that reads the token from the environment inside the helper and uses an Authorization header if the provider supports it; rotate the token 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:231
Finding
API Token Exposed Through Process Arguments and URL Query Parameters## Vulnerability Details **File Location**: `bin/run.mjs:20-25, 76-98, 139-155, 185-195, 231-237`; `SKILL.md:42, 49-50` **Vulnerability Type**: Sensitive credential exposure **Risk Level**: Medium ### Vulnerable Code `bin/run.mjs:20-25` ```js { "defaultValue": null, "description": "Authentication token required for API access.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" } ``` `bin/run.mjs:76-98` ```js 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", }, method: operation.method, }; if (operation.requestBody && params.body !== undefined) { requestInit.body = JSON.stringify(params.body); requestInit.headers["content-type"] = operation.requestBody.contentType || "application/json"; } let response; try { response = await fetch(url, requestInit); ``` `bin/run.mjs:139-155` ```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; } ``` `bin/run.mjs:185-195` ```js function injectToken(operation, params, cliToken) { const tokenParam = operation.parameters.find((parameter) => parameter.name === "token"); ...[truncated 3045 chars]
Remediation
## Remediation Suggestions 1. Read the token directly from `process.env.JUST_ONE_API_TOKEN` inside the Node process instead of requiring `--token`. This prevents ordinary command-line process listings from exposing the value. 2. If supported by JustOneAPI, transmit the credential in an `Authorization` header rather than in the URL: ```js 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}`, }, }; ``` 3. Remove `token` from the generic query-parameter manifest and prevent user-supplied `params.token` values from overriding the trusted credential source. 4. If the backend requires query authentication and cannot be changed, request a server-side authentication redesign. Until then, ensure clients, reverse proxies, API gateways, observability systems, and server logs redact the `token` query parameter. 5. Update `SKILL.md` so the invocation does not place the token on the command line: ```bash JUST_ONE_API_TOKEN="$JUST_ONE_API_TOKEN" node {baseDir}/bin/run.mjs --operation "getTwitterUserPostsV1" --params-json '{"restId":"user-rest-id"}' ``` 6. Avoid including complete request URLs in errors, traces, analytics, or debug output, and rotate any token suspected of having been logged or exposed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Missing User Warnings

High
Confidence
97% confidence
Finding
The manifest requires a `token` query parameter for a third-party service but provides no user-facing warning that credentials will be transmitted to JustOneAPI. Sending secrets as a query parameter is especially risky because query strings are commonly logged by clients, proxies, gateways, and observability systems, increasing the chance of credential leakage and downstream account misuse.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill invokes a network-capable helper (`node .../bin/run.mjs`) and sends authenticated requests to an external API, but it does not declare an explicit tool scope such as `permissions` or `allowed-tools`. This weakens policy enforcement and reviewability because an agent may be allowed to perform outbound network actions without a clear, machine-readable restriction boundary.

Vague Triggers

Medium
Confidence
87% confidence
Finding
This JSON manifest describes the skill in general terms as calling an API for Twitter user posts, but it does not specify any narrow trigger phrases, invocation scope, or exclusion conditions. For manifest files, such lack of specificity can cause overly broad or unintended invocation because there is no clear boundary for when the skill should or should not activate.

Static analysis

Detected: suspicious.secret_argv_exposure

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:42