T09 · Insecure Skill Coding Practices
Warning
- Location
- solpaw-skill.ts:83
- Finding
- API Credential Disclosure Through an Unrestricted Configurable Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `solpaw-skill.ts:83-117` **Vulnerability Type**: Credential disclosure through an unvalidated network destination **Risk Level**: Medium ### Vulnerable Code ```typescript constructor(config: SolPawConfig) { if (!config.apiEndpoint) throw new Error("SolPaw: apiEndpoint is required"); if (!config.apiKey) throw new Error("SolPaw: apiKey is required"); if (!config.defaultCreatorWallet) throw new Error("SolPaw: defaultCreatorWallet is required"); this.config = { ...config, apiEndpoint: config.apiEndpoint.replace(/\/$/, ""), }; } /** * Make an authenticated request to the SolPaw API. * API key is sent in the Authorization header — never in query params or body. */ private async request<T>( method: string, path: string, body?: Record<string, unknown>, headers?: Record<string, string> ): Promise<T> { const url = `${this.config.apiEndpoint}${path}`; const response = await fetch(url, { method, headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.config.apiKey}`, ...headers, }, body: body ? JSON.stringify(body) : undefined, signal: AbortSignal.timeout(120000), }); ``` ### Technical Analysis The constructor accepts any nonempty `apiEndpoint` and performs no scheme, hostname, port, or origin validation. The common request function subsequently sends the configured API key in an `Authorization: Bearer` header to that endpoint on every request. As a result, configuration manipulation can redirect credentials and request data to an unrelated server. The implementation also does not require HTTPS, so a configuration using plain HTTP could expose credentials to network interception. Depending on the invoked method, transmitted information can include: - The SolPaw API key - Creator wallet addresses - Launch-fee transaction signatures - Token names, symbols, descriptions, and social links - CSRF tokens - Account-spec ...[truncated 1796 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the endpoint with the standard `URL` class and reject malformed values. 2. Require `https:` for all authenticated remote endpoints. 3. For the hosted version, allowlist the expected origin: ```typescript const endpoint = new URL(config.apiEndpoint); const allowedOrigin = "https://api.solpaw.fun"; if (endpoint.protocol !== "https:" || endpoint.origin !== allowedOrigin) { throw new Error("SolPaw: untrusted API endpoint"); } ``` 4. If self-hosting support is required, make custom origins an explicit advanced option and require separate user approval before sending credentials. 5. Use separate credentials for each origin; never reuse the hosted SolPaw key with a self-hosted endpoint. 6. Ensure credentials are not forwarded across cross-origin redirects. Prefer redirect rejection for authenticated requests. 7. Add tests confirming that HTTP, alternate domains, deceptive subdomains, embedded credentials, and unexpected ports are rejected. 8. Document exactly which fields leave the host and which service receives them. ]]>
