T09 · Insecure Skill Coding Practices
Warning
- Location
- config.json:1
- Finding
- API Credentials Are Stored in a Plaintext Project Configuration File## Vulnerability Details **File Location**: `config.json`, lines 1-9; `README.md`, lines 91-109; `scripts/zai-search.js`, lines 15-21 **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: Medium The project supplies a tracked `config.json` and instructs users to place their Zhipu AI API key directly in that file. The audited directory does not contain the `.gitignore` file referenced by the documentation, creating a realistic risk that a configured API key will be committed, packaged, backed up, or otherwise disclosed with the skill directory. ### Vulnerable Code `config.json`, lines 1-9: ```json { "apiKey": "your-zhipu-api-key-here", "engine": "search_std", "intent": false, "count": 10, "recency": "noLimit", "content": "medium", "domain": "" } ``` `README.md`, lines 91-109: ```markdown # Copy example config file cp config.json.example config.json # Edit config file (with your preferred editor) # For example: vim config.json, nano config.json, or open with VS Code ``` ```json { "apiKey": "paste your API Key here", "engine": "search_std", "intent": false, "count": 10, "recency": "noLimit", "content": "medium", "domain": "" } ``` `scripts/zai-search.js`, lines 15-21: ```javascript const skillDir = path.dirname(__dirname); // scripts/.. = skill root const skillConfigPath = path.join(skillDir, 'config.json'); try { const skillConfig = JSON.parse(fs.readFileSync(skillConfigPath, 'utf8')); Object.assign(config, skillConfig); } catch {} ``` ### Technical Analysis API keys are bearer credentials: possession is generally sufficient to invoke the associated API. Storing such a credential as an ordinary plaintext file inside the skill installation directory exposes it to every process or user that can read that directory. The risk is increased because: - The distributed project already contains `config.json`, ...[truncated 2278 chars]
- Remediation
- ## Remediation Suggestions 1. **Remove `config.json` from the distributed project** - Distribute only a clearly named template such as `config.example.json`. - Ensure templates contain placeholders and never real credentials. 2. **Add and distribute an effective `.gitignore`** ```gitignore config.json *.local.json .env .env.* ``` Confirm that `config.json` is no longer tracked after adding the rule: ```bash git rm --cached config.json ``` 3. **Prefer environment-based or protected secret storage** - Make `ZAI_API_KEY` the recommended configuration mechanism. - For persistent desktop use, consider an operating-system credential manager rather than a plaintext file. - If file-based storage remains supported, prefer the user-specific path outside the skill package. 4. **Enforce restrictive file permissions** - Require user configuration directories to be mode `0700`. - Require credential-bearing files to be mode `0600`. - Warn or fail securely when a key file is readable by group or other users. 5. **Separate secret and non-secret configuration** - Keep search defaults in ordinary JSON. - Obtain the API key only from an environment variable or dedicated secret provider. 6. **Reject placeholder credentials** ```javascript const PLACEHOLDERS = new Set([ 'your-zhipu-api-key-here', 'your-api-key-here' ]); if (!apiKey || PLACEHOLDERS.has(apiKey)) { throw new Error('Configure ZAI_API_KEY with a valid API key.'); } ``` 7. **Update all documentation** - Stop describing skill-folder storage as the recommended option. - Clearly warn users never to commit, package, log, or share API keys. - Correct the documented file structure so it matches the distributed files. 8. **Respond to any prior exposure** - Review repository history and published packages for populated copies of `conf ...[truncated 163 chars]
