T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:306- Finding
API Credential Exposure Through URL Query Parameters and Process Arguments
- Content
View full analysis
Vulnerability Details
File Location:
bin/run.mjs:23-31,bin/run.mjs:278-286,bin/run.mjs:306-313; related invocation guidance atSKILL.md:41
Vulnerability Type: API credential exposure
Risk Level: MediumVulnerable Code
js { "defaultValue": null, "description": "Access token for this API service.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }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; }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); } }The documented invocation also passes the credential as a command-line argument:
bash node {baseDir}/bin/run.mjs --operation "<operation-id>" --token "$JUST_ONE_API_TOKEN" --params-json '{"key":"value"}'Technical Analysis
The Skill inserts
JUST_ONE_API_TOKENintoURL.searchParams, resulting in requests whose URLs contain the credential as atokenquery parameter. HTTPS protects the request from ordinary passive network interception, but it does not prevent the complete URL from being recorded by the destination service, API gateways, reverse proxies, access logs, observability platforms, debugging tools, or error telemetry.The prescribed command also supplies the secret through
--token. Command-line arguments may be vi ...[truncated 1994 chars]- Remediation
View remediation
Remediation Suggestions
-
Read the credential directly from
process.env.JUST_ONE_API_TOKENrather than accepting it through--token. -
If supported by JustOneAPI, transmit the credential in an HTTP authorization header:
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}`, }, }; -
Remove
tokenfrom operation query-parameter definitions and prevent callers from supplying a token through--params-json. -
Update
SKILL.mdso the invocation does not include a secret-bearing command-line argument. -
If the provider only supports query-string authentication:
- Retrieve the token directly from the environment.
- Configure clients, proxies, gateways, servers, and observability systems to redact the
tokenparameter. - Disable storage of complete query strings where possible.
- Ensure errors and diagnostics never include the complete request URL.
- Use narrowly scoped, short-lived tokens and implement routine rotation.
-
Revoke and replace any token suspected of appearing in process captures, URL logs, or telemetry.
-
