T09 · Insecure Skill Coding Practices
- Location
src/utils/request.js:91- Finding
API Credential Exposed in URL Query Parameters
- Content
View full analysis
Vulnerability Details
File Location:
src/utils/request.js, lines 91-120; credential parameters originate from API modules such assrc/api/search.js, lines 59-61
Vulnerability Type: Sensitive credential exposure through request URLs
Risk Level: MediumVulnerable Code
javascript // src/api/search.js const params = { _: Date.now(), token: token, };javascript // src/utils/request.js params.skill_name = skillName(); const fullPath = `${path}?${querystring.stringify(params)}`; const jsonData = JSON.stringify(data); const options = { host: constants.BASE_URL, path: fullPath, method: "POST", headers: { "Content-Type": "application/json", "Accept-Encoding": "identity", "Content-Length": Buffer.byteLength(jsonData), }, }; return await request(options, jsonData);The same pattern is used by the search, post, comment, and hot API operations.
Technical Analysis
The value of
GUAIKEI_API_TOKENis inserted into theparamsobject and serialized into the URL query string. Consequently, requests use URLs resembling:text https://www.guaikei.com/api/douyin/general-search/keyword?token=SECRET&...HTTPS protects the query string while it is in transit, but it does not prevent the complete URL from being recorded after TLS termination. Query strings are commonly captured by:
- Reverse-proxy and load-balancer access logs
- API gateway and web server logs
- Application performance monitoring systems
- Network debugging tools
- Error reports and request tracing systems
- Upstream analytics or observability services
The credential is repeatedly included in both task-creation and polling requests. Polling may run up to 20 times, increasing the number of records containing the token.
Authentication secrets should be transmitted in an HTTP authorization header rather than in a URL. The source review found no evi ...[truncated 1471 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the token from every query-parameter object.
-
Send the credential in an HTTP authorization header:
javascript const options = { host: constants.BASE_URL, path: fullPath, method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", "Accept-Encoding": "identity", "Content-Length": Buffer.byteLength(jsonData), }, }; -
Refactor
postJsonandgetJsonto accept the token separately from ordinary parameters, preventing accidental serialization. -
Ensure client-side error messages, tracing, and debug logs redact
Authorization,token, and equivalent secret fields. -
Configure the server, reverse proxies, and API gateways to redact historical query parameters.
-
Rotate existing tokens because prior invocations may already have placed them in access logs.
-
Prefer short-lived, narrowly scoped tokens with revocation and usage-monitoring support.
-
Add automated tests asserting that generated request paths never contain the token.
-
