T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/setup.js:18
- Finding
- Bearer API Credentials Can Be Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup.js:18-32`, `scripts/setup.js:75-98`, `scripts/api.js:23-44` **Vulnerability Type**: Cleartext transmission of bearer credentials **Risk Level**: High ### Vulnerable Code ```js function testApiKey(apiUrl, apiKey) { return new Promise((resolve, reject) => { const url = new URL(apiUrl + '/integrations/me'); const isHttps = url.protocol === 'https:'; const lib = isHttps ? https : http; const options = { hostname: url.hostname, port: url.port || (isHttps ? 443 : 80), path: url.pathname, method: 'GET', headers: { 'Authorization': `Bearer ${apiKey}`, 'User-Agent': 'OurProject-OpenClaw-Skill/1.0' }, }; ``` ```js // API URL const apiUrl = await ask(`API URL [${DEFAULT_API_URL}]: `); const finalApiUrl = apiUrl.trim() || (existingConfig?.apiBaseUrl || DEFAULT_API_URL); // API Key const apiKey = await ask('API Key (starts with op_): '); if (!apiKey.trim()) { console.error('❌ API key is required. Get one from Integrations → API Keys.'); rl.close(); process.exit(1); } if (!apiKey.trim().startsWith('op_')) { console.error('❌ Invalid API key format. Must start with "op_"'); rl.close(); process.exit(1); } // Test connection console.log('\n🔍 Testing connection...'); try { const result = await testApiKey(finalApiUrl, apiKey.trim()); ``` ```js function makeRequest(method, endpoint, body = null) { const config = loadConfig(); return new Promise((resolve, reject) => { const baseUrl = config.apiBaseUrl || 'https://api.ourproject.app/api'; // Normalize: if endpoint already has /api/ prefix, strip it since baseUrl already includes /api const normalizedEndpoint = endpoint.startsWith('/api/') ? endpoint.slice(4) : endpoint; const fullEndpoint = normalizedEndpoint.startsWith('/') ? normalizedEndpoi ...[truncated 2716 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Reject all API URLs whose protocol is not exactly `https:` before any request is made. 2. Prefer a fixed, trusted production origin such as `https://api.ourproject.app`. 3. If custom hosts are a legitimate requirement, require explicit confirmation and maintain an allowlist of approved HTTPS origins. 4. Normalize and validate the URL with the `URL` API before combining it with endpoint paths. 5. Ensure authorization headers are never forwarded across cross-origin redirects. 6. Apply normal TLS certificate and hostname verification without disabling Node.js certificate checks. 7. Document that development HTTP endpoints must never be used with production credentials. 8. Revoke and rotate any API key that may previously have been transmitted over HTTP. Example validation: ```js function validateApiUrl(value) { const url = new URL(value); if (url.protocol !== 'https:') { throw new Error('The API URL must use HTTPS.'); } return url.toString().replace(/\/+$/, ''); } ``` ]]>
