T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/calibredb_apply.mjs:214
- Finding
- Calibre Credentials Exposed Through Process Arguments and Automatic Fallback-Host Probing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/calibredb_apply.mjs:214-239, 286-290, 320-338` **Vulnerability Type**: Credential exposure and excessive network trust **Risk Level**: Medium ### Vulnerable Code ```js const extraHosts = [ ...splitList(args['server-hosts']), ...SERVER_HOSTS_ENV_KEYS.flatMap(k => splitList(process.env[k])), ...discoverWslHostCandidates(), 'host.docker.internal', ] .map(normalizeHostToken) .filter(Boolean); for (const c of baseCandidates) { const normalized = normalizeWithLibrary(c.value, libraryId); expanded.push({ source: c.source, value: normalized }); if (!isHttpUrl(normalized)) continue; const p = parseHttpUrlParts(normalized); if (!p) continue; const curHost = normalizeHostToken(p.host); for (const h of extraHosts) { if (!h || h === curHost) continue; expanded.push({ source: `${c.source}:host=${h}`, value: replaceHttpHost(normalized, h) }); } } ``` ```js function probeRemoteLibrary(withLibrary, auth) { const cmd = [ 'calibredb', 'list', '--for-machine', '--fields', 'id', '--limit', '1', '--with-library', withLibrary ]; if (auth.username) cmd.push('--username', String(auth.username)); if (auth.password) cmd.push('--password', String(auth.password)); return run(cmd); } ``` ```js function resolveAuth(args) { const envUser = (process.env.CALIBRE_USERNAME || '').trim(); const username = args.username ? String(args.username) : (envUser || null); let password = args.password ? String(args.password) : ''; const passwordEnv = args['password-env'] ? String(args['password-env']) : 'CALIBRE_PASSWORD'; if (!password && passwordEnv) { password = process.env[passwordEnv] || ''; } return { username, password, usedPasswordEnv: passwordEnv }; } function commonArgs(args, auth) { const r = ['--with-library', String(args['with-library'])]; if (auth.username) r.push('--username', String(auth.username)); if (auth.pas ...[truncated 2951 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove implicit fallback candidates such as WSL resolver addresses and `host.docker.internal`. 2. Use only explicitly configured hosts by default. If fallback is needed, require an explicit allowlist and separate user approval. 3. Bind authentication credentials to an exact scheme, host, port, and library identifier. Do not reuse them after automatic host substitution. 4. Require HTTPS for non-loopback remote servers and validate the server certificate. 5. Remove support for `--password <plain>` from the wrapper interface. 6. Avoid placing plaintext secrets in process arguments. Use a protected file descriptor, standard input, an OS credential facility, or another secret-passing mechanism supported by `calibredb`. 7. If no secure credential-passing mechanism is available, document the process-list exposure and isolate execution under a dedicated operating-system account. 8. Keep redaction for logs and errors, but do not treat redaction as protection for the live argument vector. 9. Add tests confirming that authentication is never attempted against a host not present in an explicit allowlist. ]]>
