T09 · Insecure Skill Coding Practices
Warning
- Location
- index.js:26
- Finding
- Configurable API Base URL Can Expose the Bearer Token to an Arbitrary Server## Vulnerability Details **File Location**: `index.js`, lines 26–50 **Vulnerability Type**: Unvalidated destination for authenticated API requests **Risk Level**: Medium ### Vulnerable Code ```js async function apiRequest(method, endpoint, body = null) { const config = loadConfig(); const apiKey = config.apiKey; const baseUrl = config.baseUrl || 'https://socialrails.com/api/v1'; if (!apiKey) { return { error: 'SocialRails API key not configured. Run: openclaw config socialrails apiKey <your-key>' }; } const options = { method, headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, }; if (body) { options.body = JSON.stringify(body); } const url = `${baseUrl}${endpoint}`; try { const response = await fetch(url, options); ``` ### Technical Analysis The skill reads `baseUrl` from user-controlled configuration and uses it without validating its scheme, hostname, port, or origin. It then attaches the SocialRails API key to every request through the `Authorization` header. Consequently, anyone able to influence `skills.socialrails.baseUrl` in `~/.openclaw/openclaw.json` can redirect authenticated requests to a server they control. The implementation also permits an `http://` URL, allowing the credential and request contents to be transmitted without transport encryption. This is a credential-disclosure flaw rather than remote code execution. Exploitation requires the ability to alter or socially engineer a change to the skill configuration. ### Attack Path 1. An attacker persuades the user to configure a purported proxy or alternative SocialRails endpoint, or otherwise gains the ability to modify `skills.socialrails.baseUrl`. 2. The attacker sets `baseUrl` to a server they control, such as `https://attacker.example/api/v1`. 3. The user invokes any skill command that calls `apiRequest`. 4. The ...[truncated 857 chars]
- Remediation
- ## Remediation Suggestions 1. Parse the configured value with `new URL()` rather than concatenating unvalidated strings. 2. Require the `https:` scheme and reject plaintext HTTP. 3. Allowlist the official `socialrails.com` hostname and expected API path. 4. Reject embedded credentials, unexpected ports, malformed URLs, and unapproved subdomains. 5. If custom endpoints are necessary, require an explicit high-risk opt-in and use separate credentials that are not valid against the production SocialRails service. 6. Before attaching the `Authorization` header, verify that the final request URL remains on an approved origin. 7. Prevent credential forwarding across redirects, or disable redirects and validate each redirect destination. 8. Document that changing `baseUrl` can disclose API credentials and should only be performed for trusted endpoints.
