T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:224- Finding
API Access Token Exposed Through Command-Line Arguments and URL Query Parameters
- Content
View full analysis
Vulnerability Details
File Location:
bin/run.mjs:17-27,bin/run.mjs:65-67,bin/run.mjs:139-159,bin/run.mjs:173-185, andbin/run.mjs:224-233
Vulnerability Type: Sensitive credential exposure
Risk Level: MediumThe Skill legitimately requires a JustOneAPI access token, but it accepts that token through a command-line argument and transmits it as a URL query parameter.
Relevant operation declaration from
bin/run.mjs:17-27:js { "defaultValue": null, "description": "Access token for this API service.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }Relevant request construction from
bin/run.mjs:65-67: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);Command-line token handling from
bin/run.mjs:139-159: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; }Token injection from
bin/run.mjs:173-185:js function injectToken(operation, params, cliToken) { const tokenParam = operation.parameters.find((parameter) => parameter.name === "token"); if (!tokenParam || params.token !== ...[truncated 3864 chars]- Remediation
View remediation
Remediation Suggestions
-
Use an authorization header where supported. Remove
tokenfrom the query-parameter manifest and send it in a request header:js const token = args.token || process.env.JUST_ONE_API_TOKEN; if (!token) { fail("JUST_ONE_API_TOKEN is required."); } const requestInit = { headers: { accept: "application/json", authorization: `Bearer ${token}`, }, method: operation.method, };Confirm the exact authentication scheme required by JustOneAPI before deploying this change.
-
Read the credential directly from the environment. Prefer
process.env.JUST_ONE_API_TOKENover a--tokenargument so the secret is not included in the process argument vector. If compatibility requires--token, deprecate it and clearly warn users about process-list exposure. -
Prevent credential injection through general parameters. Reject
tokeninside--params-jsonand maintain authentication data separately from ordinary operation parameters. -
If query authentication is mandated by the upstream API, apply compensating controls.
- Configure clients, gateways, reverse proxies, and application servers to redact the
tokenquery parameter. - Disable complete-URL logging for this endpoint.
- Ensure errors and telemetry never serialize the final URL.
- Restrict access to logs and define short retention periods.
- Use narrowly scoped, short-lived, and readily revocable tokens where the service supports them.
- Configure clients, gateways, reverse proxies, and application servers to redact the
-
Add automated regression tests. Verify that tokens do not appear in process invocation examples, standard output, standard error, telemetry, or logged request URLs.
-
