T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:20
- Finding
- Molter API credential is stored without enforced restrictive permissions and exposed in command output<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 20–24, 113–117, and 140 **Vulnerability Type**: Insecure credential storage and secret disclosure through logging **Risk Level**: Medium ### Vulnerable Code ```bash cat > ~/.openclaw/workspace-molter/.env <<'EOF' MOLTER_ACCOUNT_ID= MOLTER_API_KEY= MOLTER_APP_URL=https://molter.app EOF ``` ```js const currentEnv = await readFile(envPath, "utf8"); await writeFile(envPath, upsertEnv(currentEnv, { MOLTER_ACCOUNT_ID: registration.account_id, MOLTER_API_KEY: registration.api_key, MOLTER_APP_URL: baseUrl })); ``` ```js console.log(JSON.stringify(registration, null, 2)); ``` ### Technical Analysis The onboarding flow stores a bearer-style Molter API key in a plaintext `.env` file. Persisting this credential is consistent with the Skill's recurring authenticated functionality, but the implementation does not explicitly create the workspace as mode `0700` or enforce mode `0600` on `.env`. File accessibility therefore depends on the user's umask and any existing file permissions. The registration response is also printed in full after the code reads `registration.api_key`. If the response contains the issued API key, as the surrounding logic indicates, the secret can be copied into terminal output, OpenClaw tool history, CI logs, shell-session recordings, or other log aggregation systems. Printing the credential is not necessary for the declared functionality and exceeds minimum safe secret handling. The authenticated network requests themselves are sent to the declared Molter HTTPS endpoint and are necessary for profile updates, posting, replies, and attestations. The vulnerability is the local storage and output handling, not the use of the credential as an HTTPS authentication header. ### Attack Path 1. A user or agent executes the documented Molter registration workflow. 2. Molter returns a registration object containing `account_id` and `api_key`. 3. The script writes the API key t ...[truncated 1047 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Create the workspace with owner-only access: ```bash install -d -m 0700 ~/.openclaw/workspace-molter ``` 2. Create the credential file with mode `0600` rather than relying on the current umask: ```bash install -m 0600 /dev/null ~/.openclaw/workspace-molter/.env ``` 3. Enforce permissions when updating the file in Node.js: ```js await writeFile( envPath, upsertEnv(currentEnv, { MOLTER_ACCOUNT_ID: registration.account_id, MOLTER_API_KEY: registration.api_key, MOLTER_APP_URL: baseUrl }), { mode: 0o600 } ); ``` If the file may already exist with broader permissions, explicitly correct it with `chmod(envPath, 0o600)`. 4. Never print the complete registration response. Emit only non-sensitive fields: ```js console.log(JSON.stringify({ account_id: registration.account_id, handle }, null, 2)); ``` 5. Prefer an operating-system credential store or OpenClaw-supported secret manager if one is available. Keep the key out of ordinary logs, conversation history, diagnostics, and error messages. 6. Document credential rotation and revocation procedures so an exposed key can be invalidated promptly. ]]>
