T09 · Insecure Skill Coding Practices
- Location
fetch_topics.js:598- Finding
Legacy authentication token is forwarded to arbitrary attachment and redirect hosts
- Content
View full analysis
{ const parsed = new URL(url); const reqOptions = { hostname: parsed.hostname, path: parsed.pathname + parsed.search, method: 'GET', headers: createAuthHeaders(), timeout: 30000, }; const req = https.request(reqOptions, (res) => { if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // Follow redirect return downloadFile(res.headers.location, outputPath).then(resolve).catch(reject); } ``` ### Technical Analysis `createAuthHeaders()` adds the legacy `ZSXQ_TOKEN` to a Cookie header whenever that environment variable is present. `downloadFile()` applies these authentication headers to every attachment URL without validating the destination hostname or origin. Attachment URLs originate from ZSXQ API or CLI response data and may point to CDN or other external hosts. Consequently, the Skill can send the ZSXQ authentication cookie to a host that is not `api.zsxq.com`. The redirect handling compounds the issue. Every redirect is followed recursively, and `downloadFile()` recreates the authentication headers for the redirected URL. There is no origin allowlist, cross-origin credential stripping, redirect limit, or validation of the `Location` header. This behavior can also ...[truncated 1650 chars]- Remediation
View remediation
