T09 · Insecure Skill Coding Practices
Warning
- Location
- bin/run.mjs:20
- Finding
- API Token Exposed Through URL Query Parameters and Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `bin/run.mjs:20-28`, `bin/run.mjs:91-108`; `SKILL.md:43`, `SKILL.md:50` **Vulnerability Type**: Credential exposure through insecure transport placement **Risk Level**: Medium ### Vulnerable Code `bin/run.mjs:20-28` declares the authentication token as a query parameter: ```js { "defaultValue": null, "description": "User's authentication token.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }, ``` `bin/run.mjs:91-108` injects the supplied token into the parameter collection, appends all query parameters to the request URL, and sends that URL over the network: ```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); const requestInit = { headers: { "accept": "application/json", }, method: operation.method, }; if (operation.requestBody && params.body !== undefined) { ``` `SKILL.md:43` instructs users to place the secret in a command-line argument: ```bash node {baseDir}/bin/run.mjs --operation "titleCriticsReviewSummaryQuery" --token "$JUST_ONE_API_TOKEN" --params-json '{"id":"<id>"}' ``` ### Technical Analysis The helper accepts the JustOneAPI authentication token through `--token` and stores it in `params.token`. Because the operation metadata marks `token` as a query parameter, `applyQueryParams` appends the credential to the request URL before `fetch` is called. HTTPS encrypts the request in transit, so passive network observers cannot normally read the token. However, placing credentials in URLs remains unsafe because complete URLs may be retained by reverse proxies, API gateways, web-server access logs, monitoring systems, tracing plat ...[truncated 2397 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Avoid command-line secret arguments** - Read the token directly from `process.env.JUST_ONE_API_TOKEN`. - Remove or deprecate `--token` so the secret does not appear in process arguments. - If backward compatibility is required, emit a warning and prioritize the environment variable or a protected credential provider. 2. **Move authentication out of the URL** - If supported by JustOneAPI, transmit the credential in an authorization header, for example: ```js const 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, }; ``` - Use the exact header and authentication scheme documented by JustOneAPI. - Remove `token` from the operation's query-parameter list after migrating authentication. 3. **If query authentication is mandated by the upstream API** - Continue using HTTPS, but configure all clients, proxies, gateways, access logs, tracing systems, and error handlers to redact the `token` query parameter. - Prevent request URLs containing credentials from being included in diagnostics. - Use narrowly scoped, short-lived, and readily revocable tokens where the provider supports them. 4. **Update documentation** - Replace the documented `--token "$JUST_ONE_API_TOKEN"` invocation with an environment-only workflow. - Explicitly prohibit placing the token in `--params-json`, logs, screenshots, or copied request URLs. 5. **Add regression safeguards** - Add tests asserting that secrets do not appear in process output, errors, or logged URLs. - Add static checks that reject authentication secrets declared as query parameters unless an explicit upstream compatibility exception is documented. ]]>
