T09 · Insecure Skill Coding Practices
- Location
bin/run.mjs:27- Finding
Authentication Token Exposed in URL Query String
- Content
View full analysis
Vulnerability Details
File Location:
bin/run.mjs:27-35,bin/run.mjs:98-100, andbin/run.mjs:217-226
Vulnerability Type: Authentication credential exposure through URL query parameters
Risk Level: MediumVulnerable Code
The operation manifest defines the authentication token as a query parameter:
js { "defaultValue": null, "description": "User authentication token.", "enumValues": [], "location": "query", "name": "token", "required": true, "schemaType": "string" },The token is injected into the request parameters and all query parameters are added to the URL:
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 query parameter implementation serializes the token directly into
url.searchParams: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); } }js 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 helper sends the API token in a request URL resembling:
text https://api.justoneapi.com/api/douyin-xingtu/get-kol-convert-ability/v1?token=SECRET&kolId=...&range=_1TLS protects the URL while it travels between the client and ...[truncated 3044 chars]
- Remediation
View remediation
Remediation Suggestions
-
Use an authorization header
If supported by the upstream service, remove
tokenfrom the operation's query parameters and transmit it in a header:js const requestInit = { headers: { accept: "application/json", authorization: `Bearer ${args.token}`, }, method: operation.method, }; -
Prefer environment-based credential loading
Read
JUST_ONE_API_TOKENdirectly from the environment instead of requiring the token as a command-line argument:js const token = process.env.JUST_ONE_API_TOKEN;Avoid printing the token or including it in exception details.
-
If query authentication is unavoidable
If JustOneAPI only accepts query-based authentication:
- Document the resulting logging and telemetry risks explicitly.
- Use narrowly scoped, short-lived tokens where the provider supports them.
- Configure servers, gateways, proxies, and monitoring systems to redact the
tokenparameter. - Ensure request URLs are never included in application errors or debug logs.
- Prevent URL-query data from being stored in analytics systems.
- Rotate tokens that may already have been retained in logs.
-
Update generated metadata and documentation
Change
generated/operations.json,generated/operations.md, and the embedded manifest consistently so future regeneration does not restore query-string authentication. -
Add regression tests
Add a test that constructs a request and verifies that the resulting URL does not contain
token, while confirming that the authentication header is present and is redacted from diagnostic output.
-
