T09 · Insecure Skill Coding Practices
- Location
- src/index.ts:108
- Finding
- Bearer API Key Is Written to Application Logs<![CDATA[ ## Vulnerability Details **File Location**: `src/index.ts:108-112` **Vulnerability Type**: Plaintext credential disclosure through logging **Risk Level**: High ### Vulnerable Code ```ts const keyResult = await createApiKey(hubUrl, 'OpenClaw Agent'); apiKey = keyResult.key; api.logger.info( `PersonalDataHub: Auto-created API key. Save this for your config: ${apiKey}`, ); ``` ### Technical Analysis During automatic setup, the plugin creates a bearer API key and interpolates the complete credential into an informational log message. Bearer credentials grant access based solely on possession, so they must not be exposed through logs. Application logs may be retained on disk, collected by centralized logging services, included in diagnostics, or made available to other operators and plugins. Marking the API key as sensitive in the plugin UI does not protect copies written to the logger. ### Attack Path 1. The plugin starts without a complete API key configuration. 2. It discovers or receives a reachable PersonalDataHub URL. 3. The plugin calls `/api/keys` and obtains a new bearer key. 4. The complete key is written to application logs. 5. An actor with access to local, diagnostic, or centralized logs extracts the key. 6. The actor submits authenticated requests to the configured PersonalDataHub using the exposed key. ### Impact Assessment An attacker who obtains the logged key can exercise all permissions assigned to that key. Depending on the PersonalDataHub policy, this can include retrieving authorized personal information and staging outbound actions. The exposure persists for as long as the log remains available or until the key is revoked. ]]>
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never log the plaintext API key. - Log only a non-sensitive key identifier or a short, non-reversible fingerprint. - Store newly generated credentials through the host platform's secret-management interface. - If file storage is required, use a dedicated file with owner-only permissions and atomic creation. - Add logger assertions to tests to ensure generated keys never appear in log arguments. - Revoke and replace any key that may already have been written to retained logs. - Apply redaction filters for fields and strings matching API-key formats as defense in depth. A safe replacement would be: ```ts const keyResult = await createApiKey(hubUrl, 'OpenClaw Agent'); apiKey = keyResult.key; api.logger.info( `PersonalDataHub: Auto-created API key with ID ${keyResult.id}`, ); ``` ]]>
