T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/search.js:7
- Finding
- Overbroad Loading of Credentials from a Shared Environment File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search.js:7-16`; `scripts/sources.js:7-16` **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: Medium ### Vulnerable Code The following code appears in both affected files: ```javascript // Load environment variables function loadEnv() { const envPath = path.join(process.env.HOME, '.openclaw', '.env'); if (fs.existsSync(envPath)) { const envContent = fs.readFileSync(envPath, 'utf-8'); envContent.split('\n').forEach(line => { const match = line.match(/^([^#=]+)=(.*)$/); if (match) { process.env[match[1].trim()] = match[2].trim(); } }); } } ``` ### Technical Analysis The Skill requires only `NEWSAPI_KEY`, but both scripts read the complete shared `~/.openclaw/.env` file and copy every matching `KEY=value` entry into `process.env`. This behavior exceeds the minimum access necessary for the declared NewsAPI functionality. If the shared file contains credentials for other services, those unrelated secrets become accessible to all code executing in the Node.js process. The loader also overwrites existing environment variables without checking whether they were already defined, which can unexpectedly alter trusted process configuration. The reviewed code does not transmit unrelated environment variables. The risk arises from unnecessarily broad secret access and the resulting exposure to future code changes, injected code, or compromised runtime components. ### Attack Path 1. A user stores `NEWSAPI_KEY` and unrelated service credentials in `~/.openclaw/.env`. 2. The user invokes `scripts/search.js` or `scripts/sources.js`. 3. The script reads the entire shared credential file rather than retrieving only `NEWSAPI_KEY`. 4. Every parsed entry is copied into `process.env`. 5. Any subsequently executed or compromised code in the same process can read those unrelated credentials through `process.env`. 6. The exposed credentials could t ...[truncated 808 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Prefer requiring `NEWSAPI_KEY` to be supplied directly through the process environment rather than automatically reading a shared credential file. 2. If file-based loading is necessary, parse and retrieve only the exact `NEWSAPI_KEY` entry. 3. Do not overwrite an existing `process.env.NEWSAPI_KEY` value. 4. Avoid copying unrelated file entries into `process.env`. 5. Validate that `HOME` is defined before constructing the path. 6. Restrict the credential file to owner-only permissions, such as mode `0600`. 7. Consider using a dedicated NewsAPI credential file or a platform-provided secret manager rather than a shared multi-service `.env` file. A minimal approach would be: ```javascript function loadNewsApiKey() { if (process.env.NEWSAPI_KEY) { return process.env.NEWSAPI_KEY; } const envPath = path.join(process.env.HOME, '.openclaw', '.env'); if (!fs.existsSync(envPath)) { return undefined; } const line = fs.readFileSync(envPath, 'utf8') .split(/\r?\n/) .find(entry => entry.startsWith('NEWSAPI_KEY=')); return line ? line.slice('NEWSAPI_KEY='.length).trim() : undefined; } const API_KEY = loadNewsApiKey(); ``` ]]>
