T09 · Insecure Skill Coding Practices
- Location
cli/src/config.ts:99- Finding
API Key Stored Without Enforced Owner-Only Permissions and Exposed by Configuration Command
- Content
View full analysis
{ const configPath = getConfigPath(); const current = await readConfig(configPath); const next = { ...current, ...mapConfigValue(key, value) }; await mkdir(dirname(configPath), { recursive: true }); await writeFile(configPath, `${JSON.stringify(next, null, 2)}\n`, "utf8"); } ``` `cli/src/cli.ts:428-439`: ```ts configCommand .command("get") .argument("", `One of: ${CONFIG_KEYS.join(", ")}`) .action(async (key: string) => { assertConfigKey(key); const config = await readConfig(); const mapped = getConfigValue(config, key); if (mapped) { output.write(`${mapped}\n`); } }); ``` ### Technical Analysis The `config set api-key` operation stores the NanoGPT API key as plaintext JSON. Neither the configuration directory nor the file is created with an explicit owner-only mode. Consequently, effective permissions depend on the process umask and platform defaults. On systems with permissive settings, other local users or processes may be able to read the credential. The CLI also allows `nano-gpt config get api-key` to print the complete API key to standard output. This is inconsistent with `config list`, which applies `redactConfig`. Full disclosure increases the risk of leakage through terminal history capture, CI logs, process wrappers, support transcripts, or command output collected by automation. No privilege escalation is required beyond local read access to an insufficiently protected file or access to captured command output. ### Attack Path 1. A user runs `nano-gpt config set api-key `. 2. The CLI creates or overwrites `config.json` without explicitly enforcing mode ...[truncated 862 chars]- Remediation
View remediation
