T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:236- Finding
API Token Exposed Through Command-Line Arguments and URL Query Parameters
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:40,47;bin/run.mjs:18-27,62-68,141-145,236-251;generated/operations.json:15-24;generated/operations.md:19
Vulnerability Type: Credential exposure through process arguments and request URLs
Risk Level: MediumThe Skill legitimately requires a JustOneAPI access token to perform its declared JD.com product-list lookup. However, it passes the token through a command-line argument and subsequently places it in an HTTPS URL query parameter.
Relevant documented invocation:
bash node {baseDir}/bin/run.mjs --operation "getJdShopItemListV1" --token "$JUST_ONE_API_TOKEN" --params-json '{"shopId":"<shopId>"}'Relevant parameter declaration:
js { "defaultValue": null, "description": "Access token for this API service.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }Relevant token-processing and request-construction code:
js 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);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[pa ...[truncated 3451 chars]- Remediation
View remediation
Remediation Suggestions
- Read
JUST_ONE_API_TOKENdirectly fromprocess.envinsidebin/run.mjsrather than requiring the token through--token. Remove or deprecate the command-line token option to prevent exposure through process listings and command telemetry. - If supported by JustOneAPI, transmit the token in a dedicated authentication header, such as:
js const requestInit = { method: operation.method, headers: { accept: "application/json", authorization: `Bearer ${process.env.JUST_ONE_API_TOKEN}`, }, }; - Remove
tokenfrom the operation's query-parameter definitions so generic query construction cannot accidentally append it to the URL. - If the service contract mandates query authentication, document that limitation explicitly, ensure URLs are never logged, and configure reverse proxies, API gateways, monitoring systems, and server access logs to redact the
tokenparameter. - Add centralized redaction for sensitive field names such as
token,authorization, andapiKeybefore writing errors or telemetry. - Avoid printing constructed request URLs when handling failures. Add automated tests verifying that credentials do not appear in command lines, generated URLs, standard output, standard error, or diagnostic records.
- Rotate any token suspected of having been captured in process or URL logs and apply the narrowest available token permissions, quotas, and expiration period.
- Read
