T09 · Insecure Skill Coding Practices
Warning
- Location
- bin/run.mjs:19
- Finding
- API Token Exposed Through Process Arguments and URL Query Parameters## Vulnerability Details **File Location**: `bin/run.mjs:19-27, 69-86, 159-171, 208-217`; `SKILL.md:39, 46` **Vulnerability Type**: Sensitive credential exposure **Risk Level**: Medium The Skill legitimately requires a JustOneAPI token and sends requests only to the fixed, documented HTTPS endpoint. However, the token is supplied through a command-line argument and subsequently placed in the request URL's query string. ### Complete Code Snippets `SKILL.md:39` documents passing the secret as a command-line argument: ```bash node {baseDir}/bin/run.mjs --operation "getDouyinVideoDetailV2" --token "$JUST_ONE_API_TOKEN" --params-json '{"videoId":"<videoId>"}' ``` `bin/run.mjs:19-27` defines the token as a query parameter: ```javascript { "defaultValue": null, "description": "Access token for this API service.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }, ``` `bin/run.mjs:69-86` constructs the URL and sends the request: ```javascript 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:159-171` accepts the token from the command line: ```javascript 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]; ...[truncated 3221 chars]
- Remediation
- ## Remediation Suggestions 1. Read the token directly from `process.env.JUST_ONE_API_TOKEN` instead of requiring a `--token` command-line argument: ```javascript const token = process.env.JUST_ONE_API_TOKEN; if (!token) { fail("JUST_ONE_API_TOKEN is required."); } ``` 2. Prefer a standard authentication header if supported by JustOneAPI: ```javascript const requestInit = { method: operation.method, headers: { accept: "application/json", authorization: `Bearer ${token}`, }, }; ``` 3. Remove the token from the operation's query-parameter collection so generic query construction cannot accidentally append it to the URL. 4. If the upstream service only supports query-string authentication, document this residual risk and configure clients, proxies, gateways, monitoring platforms, and access logs to redact the `token` parameter. 5. Ensure failures and diagnostics never print the complete request URL or serialized parameter object. 6. Rotate any token suspected of appearing in process accounting, logs, screenshots, shell history, or diagnostic records. 7. Restrict token permissions and quotas to the minimum API scope required for the video-detail operation.
