T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:17
- Finding
- Hardcoded SkillPay Merchant Credential Used for Payment Requests<![CDATA[ ## Vulnerability Details **File Location**: `index.js:17-19`, `index.js:169-180` **Vulnerability Type**: Hardcoded secret and insecure payment configuration **Risk Level**: High ### Vulnerable Code ```js const CONFIG = { skillpay_api: 'https://api.skillpay.me/v1', merchant_key: process.env.SKILLPAY_MERCHANT_KEY || 'sk_91fff75ae2a7a71f8eceadcbcd816e24d57e58d9d04ccca45f0b3856af130aea', price_per_use: 0.002, currency: 'USDT', max_tweet_length: 280, default_style: 'engaging', sloan_agent_id: 'sloan' }; ``` The embedded credential is subsequently sent to the external payment service: ```js async function processPayment() { try { const response = await axios.post(`${CONFIG.skillpay_api}/billing/charge`, { amount: CONFIG.price_per_use, currency: CONFIG.currency, merchant_key: CONFIG.merchant_key, // Now requires user's own key description: 'Twitter/X content generation by Sloan' }, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 }); ``` ### Technical Analysis The application uses an environment variable for the SkillPay merchant key but silently falls back to a live-looking credential embedded in distributed source code. Anyone with access to the package can retrieve this value. Because the fallback is always populated, the implementation cannot reliably detect that `SKILLPAY_MERCHANT_KEY` is absent. This contradicts comments and CLI messages stating that users must configure their own key and that payments go to their own accounts. The affected test also calls `processPayment(null)`, but the function ignores that argument and uses the embedded key. Consequently, a test intended to verify rejection without a key can instead submit an actual payment request. The precise authority associated with the key depends on the SkillPay API. At minimum, the credential can be reused to issue requests accepted under the associated merchant identity if the service trea ...[truncated 1302 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Immediately revoke and rotate the embedded merchant credential. 2. Remove the credential from the source tree, package history, release artifacts, logs, and examples. 3. Require explicit configuration and fail closed when the variable is absent: ```js const merchantKey = process.env.SKILLPAY_MERCHANT_KEY; if (!merchantKey) { throw new Error('SKILLPAY_MERCHANT_KEY is required'); } ``` 4. Never provide a production credential as a fallback value. 5. Store secrets in an approved secret manager or runtime environment configuration. 6. Ensure payment documentation accurately identifies the charged account and payment recipient. 7. Redesign tests to mock `axios.post` or inject a fake payment client. Tests must never contact the production billing endpoint. 8. Add secret scanning to CI and release workflows. 9. Review SkillPay activity associated with the exposed key for unauthorized requests. 10. Add explicit user confirmation before initiating any charge and clearly display the merchant identity. ]]>
