T09 · Insecure Skill Coding Practices
Warning
- Location
- bin/run.mjs:224
- Finding
- API Access Token Transmitted in the URL Query String<![CDATA[ ## Vulnerability Details **File Location**: `bin/run.mjs:21-28`, `bin/run.mjs:71-74`, and `bin/run.mjs:224-231` **Vulnerability Type**: Sensitive credential exposure through URL query parameters **Risk Level**: Medium ### Vulnerable Code ```js { "defaultValue": null, "description": "Access token for this API service.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" } ``` ```js 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, }; ``` ```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); } } function appendValue(searchParams, name, value) { if (Array.isArray(value)) { for (const item of value) { appendValue(searchParams, name, item); } return; } if (value && typeof value === "object") { searchParams.append(name, JSON.stringify(value)); return; } searchParams.append(name, String(value)); } ``` ### Technical Analysis The operation definition classifies the API access token as a query parameter. The generic query-parameter builder consequently inserts the credential into the final request URL, producing a request resembling: ```text https://api.justoneapi.com/api/xiaohongshu/search-user/v2?token=SECRET&keyword=VALUE&page=1 ``` Although the request uses HTTPS, TLS only protects the URL while it is in transit. The complete URL may still be recorded by the API server, reverse proxies, content-delivery infrastructure, observability systems, application performance monitoring tools, network diagnostics, or error-r ...[truncated 1778 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Change the service contract to accept credentials through an authorization header, preferably: ```js const requestInit = { method: operation.method, headers: { accept: "application/json", authorization: `Bearer ${token}`, }, }; ``` 2. Remove `token` from the operation's query-parameter definitions so the generic query builder cannot append it to the URL. 3. Update `generated/operations.json`, `generated/operations.md`, and `SKILL.md` to document header-based authentication. 4. If the upstream API cannot immediately support headers, configure all API gateways, proxies, server logs, tracing systems, and error-reporting tools to redact the `token` query parameter. 5. Prevent complete request URLs containing credentials from appearing in errors or telemetry. 6. Use narrowly scoped, short-lived credentials and provide token rotation and revocation mechanisms. 7. Add an automated test asserting that serialized request URLs never contain the API token. ]]>
