T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:11
- Finding
- Hard-Coded SkillPay Billing API Credential## Vulnerability Details **File Location**: `index.js:11`, with credential use at `index.js:129-141` and additional disclosure at `index.js:218-222` **Vulnerability Type**: Hard-coded secret and exposed billing credential **Risk Level**: High ### Vulnerable Code ```js this.skillPayApiKey = process.env.SKILL_BILLING_API_KEY || 'sk_2842f59e03e64e418c15771b0928c3f94a1f1da73ae7e72adc8f483e9f6fe6b1'; ``` The credential is transmitted to the external billing service as follows: ```js async callSkillPayAPI(endpoint, params) { const BILLING_URL = "https://skillpay.me/api/v1/billing"; const HEADERS = { "X-API-Key": this.skillPayApiKey, "Content-Type": "application/json" }; try { const response = await fetch(BILLING_URL + endpoint, { method: 'POST', headers: HEADERS, body: JSON.stringify(params) }); ``` It is also repeated in setup guidance: ```js return '❌ 请设置 SKILL_BILLING_API_KEY 环境变量:\n' + 'export SKILL_BILLING_API_KEY="sk_2842f59e03e64e418c15771b0928c3f94a1f1da73ae7e72adc8f483e9f6fe6b1"\n' + 'export SKILL_ID="usage-tracker-clawhub"\n' + '@openclaw setup YOUR_API_KEY'; ``` ### Technical Analysis The application uses an embedded credential as the fallback whenever `SKILL_BILLING_API_KEY` is absent. Because source packages are available to every installer, this credential must be treated as publicly disclosed. The key is placed in the `X-API-Key` header for charge, balance, and payment-link requests to `https://skillpay.me/api/v1/billing`. Network access to that service is consistent with the declared billing functionality, so the request itself is not unrelated data exfiltration. However, distributing a shared billing credential exceeds safe minimum-privilege design: every installation receives access associated with the same credential rather than a separately scoped installation credential. Environment-variable support does not m ...[truncated 1672 chars]
- Remediation
- ## Remediation Suggestions 1. Immediately revoke and rotate the exposed API key. 2. Remove the credential from source code, documentation strings, examples, package history, and published artifacts. 3. Require `SKILL_BILLING_API_KEY` to be supplied through an approved runtime secret store and fail closed when it is missing: ```js this.skillPayApiKey = process.env.SKILL_BILLING_API_KEY; if (!this.skillPayApiKey) { throw new Error('SKILL_BILLING_API_KEY is required'); } ``` 4. Provision separate credentials per installation, tenant, or deployment instead of distributing one shared key. 5. Restrict each credential to only the billing endpoints and operations required by the Skill. 6. Add expiration, rotation, rate limiting, transaction limits, and server-side audit logging. 7. Review billing logs for unauthorized use of the disclosed key. 8. Ensure errors and status output never display the key, including partial values where unnecessary.
