T09 · Insecure Skill Coding Practices
Error
- Location
- bin/moltlog.mjs:234
- Finding
- API Key Can Be Transmitted to an Arbitrary or Plaintext Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `bin/moltlog.mjs:234-235`, `bin/moltlog.mjs:267-274`, `bin/moltlog.mjs:410-412`, `bin/moltlog.mjs:468-475`, and `src/http.mjs:1-14` **Vulnerability Type**: Unrestricted authenticated network destination and insufficient transport validation **Risk Level**: High ### Vulnerable Code From `bin/moltlog.mjs:234-235`: ```js const base = args.base || process.env.MOLTLOG_API_BASE || secrets.MOLTLOG_API_BASE || 'https://api.moltlog.ai/v1'; const apiKey = process.env.MOLTLOG_API_KEY || secrets.MOLTLOG_API_KEY; ``` From `bin/moltlog.mjs:267-274`: ```js const { data, res } = await fetchJson(`${base}/posts`, { method: 'POST', headers: { 'content-type': 'application/json', 'user-agent': 'openclaw-skill/moltlog-ai', 'x-api-key': apiKey, }, body: JSON.stringify(payload), timeoutMs: 30_000, }); ``` The delete operation has the same issue at `bin/moltlog.mjs:468-475`: ```js const { data } = await fetchJson(`${base}/posts/${encodeURIComponent(id)}`, { method: 'DELETE', headers: { 'user-agent': 'openclaw-skill/moltlog-ai', 'x-api-key': apiKey, }, timeoutMs: 30_000, }); ``` From `src/http.mjs:1-14`: ```js export async function fetchJson(url, { method = 'GET', headers = {}, body, timeoutMs = 30_000 } = {}) { const ctrl = new AbortController(); const t = setTimeout(() => ctrl.abort(), timeoutMs); try { const res = await fetch(url, { method, headers: { 'accept': 'application/json', ...headers, }, body, signal: ctrl.signal, }); ``` ### Technical Analysis The authenticated `post` and `delete` operations obtain their API base URL from the `--base` argument, the `MOLTLOG_API_BASE` environment variable, or the local secrets file. The selected value is used without validating its scheme, hostname, port, or resolved address. The CLI subsequently attaches `MOLTLOG_API_KEY` as the `x-api-key` request header. An attacker who can inf ...[truncated 2152 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Default to an exact allowlist containing only the official API origin, such as `https://api.moltlog.ai`. 2. Parse configured endpoints with `new URL()` and reject: - Schemes other than HTTPS. - Embedded usernames or passwords. - Unexpected ports. - Localhost and loopback addresses. - Private, link-local, multicast, and otherwise non-public addresses. 3. If custom endpoints are required for development, require an explicit option such as `--allow-custom-base` and display a warning identifying the exact credential destination. 4. Never permit credentials to be sent over plaintext HTTP. 5. Set authenticated requests to `redirect: 'manual'` or `redirect: 'error'`. If redirects must be supported, validate every redirect destination and never forward `x-api-key` across origins. 6. Consider separating development and production credentials so a custom endpoint cannot receive a production API key. 7. Add automated tests covering malicious base URLs, plaintext URLs, private IP addresses, embedded credentials, and cross-origin redirects. 8. Ensure keys are narrowly scoped, revocable, and rotated immediately after suspected disclosure. ]]>
