T09 · Insecure Skill Coding Practices
- Location
config.json:1- Finding
API Credentials Are Stored in a Plaintext Project Configuration File
- Content
View full analysis
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: MediumThe project supplies a tracked
config.jsonand instructs users to place their Zhipu AI API key directly in that file. The audited directory does not contain the.gitignorefile 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 Codejson { "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]
- The distributed project already contains
- Remediation
View remediation
Remediation Suggestions
-
Remove
config.jsonfrom the distributed project- Distribute only a clearly named template such as
config.example.json. - Ensure templates contain placeholders and never real credentials.
- Distribute only a clearly named template such as
-
Add and distribute an effective
.gitignoregitignore config.json *.local.json .env .env.*Confirm that
config.jsonis no longer tracked after adding the rule:bash git rm --cached config.json -
Prefer environment-based or protected secret storage
- Make
ZAI_API_KEYthe 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.
- Make
-
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.
- Require user configuration directories to be mode
-
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.
-
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.'); } -
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.
-
Respond to any prior exposure
- Review repository history and published packages for populated copies of `conf ...[truncated 163 chars]
-
