T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:164- Finding
API Credential Exposed Through Command-Line Arguments and URL Query Parameters
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:37,SKILL.md:44,bin/run.mjs:164-177,bin/run.mjs:210-217
Vulnerability Type: API credential exposure
Risk Level: MediumThe documented invocation passes the JustOneAPI token as a command-line argument:
bash node {baseDir}/bin/run.mjs --operation "getPostCommentV1" --token "$JUST_ONE_API_TOKEN" --params-json '{"awemeId":"<awemeId>"}'The executable then injects that credential 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; }Because the manifest defines
tokenas a query parameter, the following code places the credential in the request URL: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); } }Technical Analysis
The token is exposed through two sensitive channels:
- Passing it through
--tokenplaces it in the process argument vector. Depending on operating-system permissions and deployment configuration, command arguments may be visible through process inspection, execution auditing, monitoring agents, or command logging. - Adding it to
URL.searchParamsproduces a URL containing?token=.... Although HTTPS encrypts the request in transit, full URLs can still be retained by API gateways, reverse proxies, server access logs, observability systems, error reports, or redirect ha ...[truncated 1541 chars]
- Passing it through
- Remediation
View remediation
Remediation Suggestions
-
Read
JUST_ONE_API_TOKENdirectly fromprocess.envrather than requiring the secret through--token:js const token = process.env.JUST_ONE_API_TOKEN;Remove or deprecate the command-line token option so credentials do not appear in the process argument vector.
-
If supported by JustOneAPI, transmit the credential in an authorization header:
js requestInit.headers.authorization = `Bearer ${token}`;Update the API contract and manifest so
tokenis not treated as a query parameter. -
If the upstream service strictly requires query-string authentication:
- Never log the complete request URL.
- Redact
tokenfrom application, proxy, gateway, monitoring, tracing, and error logs. - Disable automatic cross-origin redirects or ensure credentials are removed before following redirects.
- Configure the shortest practical log-retention period and restrict access to infrastructure logs.
- Rotate the token immediately if URL or process records may already have exposed it.
-
Use narrowly scoped, revocable credentials with rate and spending limits where supported. Maintain separate tokens for development and production.
-
Update
SKILL.mdto document environment-based token loading and explicitly prohibit passing secrets through command-line arguments orparams-json.
-
