T09 · Insecure Skill Coding Practices
- Location
- bin/lobster.js:14
- Finding
- Arbitrary server configuration can redirect sensitive requests<![CDATA[ ## Vulnerability Details **File Location**: `bin/lobster.js:14`, `bin/lobster.js:52-61`, `bin/lobster.js:91-108`, `bin/lobster.js:214-220`, `bin/lobster.js:287-293` **Vulnerability Type**: Unrestricted credential-bearing network destination and plaintext transport **Risk Level**: High ### Vulnerable Code ```js // bin/lobster.js:14 const DEFAULT_SERVER = process.env.LOBSTER_URL || 'https://lobster.fun'; ``` ```js // bin/lobster.js:52-61 async function api(endpoint, options = {}) { const config = loadConfig(); const url = `${config.server}${endpoint}`; try { const res = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...options.headers } }); ``` ```js // bin/lobster.js:91-108 program .command('config') .description('Configure Lobster CLI') .option('-s, --server <url>', 'Set server URL') .option('--show', 'Show current config') .action((opts) => { const config = loadConfig(); if (opts.show) { console.log('🦞 Lobster Config:'); console.log(` Server: ${config.server}`); console.log(` Config: ${CONFIG_FILE}`); return; } if (opts.server) { config.server = opts.server; saveConfig(config); console.log(`✅ Server set to: ${opts.server}`); } }); ``` ```js // bin/lobster.js:214-220 const result = await api('/api/stream/say', { method: 'POST', body: JSON.stringify({ agentId: session.agentId, secret: session.secret, text }) }); ``` ```js // bin/lobster.js:287-293 await api('/api/stream/end', { method: 'POST', body: JSON.stringify({ agentId: session.agentId, secret: session.secret }) }); ``` ### Technical Analysis The CLI permits `config.server` to be supplied through either the `LOBSTER_URL` environment variable or the persistent `lobster config --server` option. It does not parse or validate the value, require HTTPS, restrict the destination to the declared Lob ...[truncated 2013 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse server values with `new URL()` and reject malformed URLs. 2. Require the `https:` protocol for all credential-bearing requests. 3. Restrict production operation to an explicit host allowlist, preferably exactly `lobster.fun`. 4. If custom servers are a required development feature: - Require an explicit development-mode flag. - Display the normalized destination. - Require interactive confirmation before transmitting credentials. - Never enable custom credential-bearing destinations silently through an environment variable. 5. Store separate credentials per origin and refuse to reuse a credential or session secret after the configured origin changes. 6. Clear existing session state whenever the server is changed. 7. Consider certificate or public-key pinning where operationally practical. 8. Add automated tests confirming rejection of HTTP, malformed URLs, user-info URLs, unexpected ports, and unapproved hosts. ]]>
