T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:184- Finding
API Authentication Token Exposed in URL Query String
- Content
View full analysis
Vulnerability Details
File Location:
bin/run.mjs:31-39,bin/run.mjs:83-91,bin/run.mjs:124-132,bin/run.mjs:184-197, andbin/run.mjs:328-336
Vulnerability Type: Credential exposure through URL query parameters
Risk Level: MediumVulnerable Code
The authentication token is defined as a query parameter for each supported operation:
js { "defaultValue": null, "description": "User authentication token.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" }The token is injected into the general parameter object before the request URL is constructed:
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);The resulting URL, including the token, is transmitted to the fixed JustOneAPI endpoint:
js let response; try { response = await fetch(url, requestInit); } catch (error) { fail("Network request failed.", { cause: error instanceof Error ? error.message : String(error), operationId: operation.operationId, }); }Query parameters are serialized directly into the 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); } } function appendValue(searchParams, name, value) { if (Array.isArray(value)) { for (const item of value) { appendValue(searchParams, name, item); ...[truncated 2726 chars]- Remediation
View remediation
Remediation Suggestions
-
Modify the API contract and client to transmit the token in an HTTP authorization header rather than in the URL:
js const requestInit = { headers: { accept: "application/json", authorization: `Bearer ${args.token}`, }, method: operation.method, }; -
Remove
tokenfrom the operation query-parameter definitions and ensure it cannot be supplied through--params-json. -
Avoid storing the credential in the general-purpose
paramsobject. Keep authentication data separate from ordinary user-controlled request parameters. -
Configure API gateways, reverse proxies, application logs, telemetry systems, and exception handlers to redact authorization credentials and any legacy
tokenquery parameter. -
If JustOneAPI only supports query-string authentication, use narrowly scoped, short-lived tokens; rotate existing tokens; disable URL query logging where possible; and apply explicit redaction before request metadata enters monitoring systems.
-
Document the residual credential-exposure risk if query-string authentication is an unavoidable provider requirement.
-
